如何将 keyof T 限制为字符串键?

Lie*_*ero 2 typescript typescript-generics

我正在尝试扩展现有接口:

type ColDef = { field: string; }
Run Code Online (Sandbox Code Playgroud)

以便我将字段值仅限于指定类型的实际属性:

interface TypeSafeColDef<T> extends ColDef {
   field: keyof T
}
Run Code Online (Sandbox Code Playgroud)

但我得到:

接口“TypeSafeColDef”错误地扩展了接口“ColDef”。属性“字段”的类型不兼容。输入'keyof TRow | undefined' 不能分配给类型 'string | 不明确的'。类型'keyof TRow' 不能分配给类型'string | 不明确的'。输入'字符串| 数量 | 符号' 不可分配给类型 'string | 不明确的'。类型 'number' 不能分配给类型 'string | 不明确的'。类型 'keyof TRow' 不能分配给类型 'string'。输入'字符串| 数量 | 符号'不可分配给类型'字符串'。“数字”类型不能分配给“字符串”类型

我试过以下约束,但没有成功

type StringKey = { [key: string]: any }

interface TypeSageColDef<TRow extends StringKey>
Run Code Online (Sandbox Code Playgroud)

for*_*d04 5

你的最后一个非常接近,我们仍然需要扩展ColDef和提取一个string键类型field

type ColDef = { field: string; }

interface TypeSafeColDef<T extends object> extends ColDef {
  field: Extract<keyof T, string>
}

// test
type T1 = TypeSafeColDef<{ a: string }> // { field: "a"; }
Run Code Online (Sandbox Code Playgroud)

field现在有 type Extract<keyof T, string>,因为从 TS 2.9 开始keyof支持string | number | symbol属性名称。如果您不想要,有一个编译器选项可以禁用此新行为。 --keyofStringsOnly

第二种选择是定义一个类型别名来摆脱Extract. 这是由于相交运算符的性质从不引发错误

type TypeSafeColDefAlias<T extends object> = ColDef & {
  field: keyof T
}
Run Code Online (Sandbox Code Playgroud)

代码示例