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

How to limit keyof T to just string keys?

我正在尝试扩展现有界面:

type ColDef = { field: string; }

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

interface TypeSafeColDef<T> extends ColDef {
   field: keyof T
}

但我得到:

Interface 'TypeSafeColDef' incorrectly extends interface 'ColDef'. Types of property 'field' are incompatible. Type 'keyof TRow | undefined' is not assignable to type 'string | undefined'. Type 'keyof TRow' is not assignable to type 'string | undefined'. Type 'string | number | symbol' is not assignable to type 'string | undefined'. Type 'number' is not assignable to type 'string | undefined'. Type 'keyof TRow' is not assignable to type 'string'. Type 'string | number | symbol' is not assignable to type 'string'. Type 'number' is not assignable to type 'string'

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

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

interface TypeSageColDef<TRow extends StringKey>

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

type ColDef = { field: string; }

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

// test
type T1 = TypeSafeColDef<{ a: string }> // { field: "a"; }

field 现在有类型 Extract<keyof T, string>,因为 keyof 支持 string | number | symbol 属性 名称 since TS 2.9. There is a compiler option --keyofStringsOnly 来禁用它新行为,如果你不想要的话。

第二种选择是定义一个类型别名来摆脱Extract。这是由于交集运算符的性质 never provoking errors:

type TypeSafeColDefAlias<T extends object> = ColDef & {
  field: keyof T
}

Code sample