为什么 keyof T 不适用于通用对象

edo*_*edo 3 typescript

我想要一个具有泛型类型的函数,T该函数必须是一个对象,并且必须至少有一个名为codetype 的属性string,然后用于keyof T获取所有对象键。

为什么这是无效的?

function TableView<T extends { code: string }>() {
    return forwardRef<HTMLDivElement, { data: T[], columns: Columns<keyof T> }>(
        (props, ref) => {
Run Code Online (Sandbox Code Playgroud)

错误:

TS2344: Type 'keyof T' does not satisfy the constraint 'string'.
Type 'string | number | symbol' is not assignable to type 'string'.
Type 'number' is not assignable to type 'string'.
Run Code Online (Sandbox Code Playgroud)

在哪里:

export interface Column<T extends string> {
    field: T;
    label: string;
    align?: "left" | "center" | "right"
    format?: "number" | "integer" | "percent" | "timestamp" | "text"
    backgroundColor?: (row: any) => string
}

type Columns<T extends string> = Column<T>[]

export default Columns
Run Code Online (Sandbox Code Playgroud)

Ale*_* L. 5

理论上T不仅可以有string钥匙(number | symbol也是允许的)。如果您只想选择string密钥 - 您可以使用Extract实用程序:

const e = Symbol();

type Foo = {
  a: string; // String-like name
  5: string; // Number-like name
  [e]: string; // Symbol-like name
};

type K1 = keyof Foo; // "a" | 5 | typeof e
type K2 = Extract<keyof Foo, string>; // "a"
Run Code Online (Sandbox Code Playgroud)

操场


Extract<Type, Union>Type通过从可分配给的所有联合成员中提取来构造类型Union


@kaya3 建议的另一个选项是使用string & keyof T交集。