Ваш последний подходит довольно близко, нам все еще нужно расширить 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"; }
field
теперь имеет тип Extract<keyof T, string>
, потому что keyof
поддерживает string | number | symbol
имена свойств , начиная с TS 2.9 . Существует опция компилятора --keyofStringsOnly
, чтобы отключить это новое поведение, если вы этого не хотите.
Второй альтернативой является определение псевдонима типа, чтобы избавиться от Extract
, Это работает из-за характера оператора пересечения , никогда не вызывающего ошибок :
type TypeSafeColDefAlias<T extends object> = ColDef & {
field: keyof T
}
Пример кода