我希望将一个类型参数T约束为具有onlystring个键,值为类型number.因此,有效的子类型如下:

type Yes_1 = { a: 1, b: 2 }

interface Yes_2 { a: number; b: number }

并且这些不是有效的子类型:

type No_1 = { a: number, b: string }

我希望能够做到以下几点:

function F<X extends Record<string, number>>() {}

如果我这样做了,它似乎会奏效:

F<Yes_1>()

Yes_2不起作用,因为它说:

F<Yes_2>()
// TS2344: Type  Yes_2  does not satisfy the constraint  Record<string, number> 
/// Index signature for type  string  is missing in type  Yes_2 

但我不希望该类型有索引签名!我做什么好?

推荐答案

您可以将X上的generic constraint更改为递归.而不是Record<string, number>,它有index signature,因此拒绝任何没有index signatureinterface(请参见microsoft/TypeScript#15300),您可以使用Record<keyof X, number>,它只关心X中存在的键:

function F<X extends Record<keyof X, number>>() { }

F<Yes_1>() // okay
F<Yes_2>() // okay
F<No_1>(); // error

我不确定您是否需要禁止非string个键,但如果是这样的话,您可以编写自己的mapped type个键,通过根据键的类型拥有conditional type个属性来实现这一效果:

function F<X extends
  { [K in keyof X]: K extends string ? number : never }
>() { }

Playground link to code

Typescript相关问答推荐

TypScript如何在 struct 上定义基元类型?

TypScript手册中的never[]参数类型是什么意思?

带有联合参数的静态大小数组

SortKey类型不起作用,尽管它使用的单个类型工作正常<>'

类型脚本泛型最初推断然后设置

泛型函数即使没有提供类型

TypeScript:在作为参数传递给另一个函数的记录中对函数的参数实现类型约束

创建一个根据布尔参数返回类型的异步函数

如何使用函数填充对象?

ANGLE找不到辅助‘路由出口’的路由路径

对于合并对象中的可选属性(例如选项),类型推断可能是错误的

在不更改类型签名的情况下在数组并集上映射文字

在类型脚本中的泛型类上扩展的可选参数

带下拉菜单的Angular 响应式选项卡

从类型脚本中元组的尾部获取第n个类型

如何在不违反挂钩规则的情况下动态更改显示内容(带有状态)?

如何在Reaction 18、Reaction-Rout6中的导航栏中获取路由参数

如何键入对象转换器

将类型脚本函数返回类型提取到VSCode中的接口

如何在TypeScript类成员函数中使用筛选后的keyof this?