这是我喜欢的类型:

type Person = {
  name: string;
  age: number;
};
type Recordable = Record<string, number | string | boolean>;
interface Column<T extends Recordable> {
  data: T;
  dataIndex?: string | number;
}
interface MyColumn<T extends Recordable> extends Column<T> {
  dataIndex: keyof T; // Error: Type 'keyof T' is not assignable to type 'string | number | undefined'.
}

TS编译器说此类型‘key of T’不能赋值给类型‘字符串|数字|未定义’.

示例:ts playground

当然,我可以对其进行重构:

interface MyColumn<T extends Recordable> extends Omit<Column<T>, 'dataIndex'> {
  dataIndex: keyof T;
}

但是,这将导致‘dataIndex’不受列约束.

我想将"dataIndex"的值约束为"Person"的属性,如下所示:

const jack: MyColumn<Person> = {
  data: { name: 'Jack', age: 1 },
  dataIndex: 'name', // name, age
};

最新情况:

我已经重构了代码,请参见ts playground.

我将interface转换为type,并使用ExtractdataIndex的类型指定为string.然而,在例2.2中,dataIndex提示Type 'string' is not assignable to type 'Extract<keyof T, string>',但在例2.1中,这是可以的.在这种情况下,是否无法推断Extract<keyof T, string>string还是never

推荐答案

有几个事实你可能不得不考虑.在你的操场上,你把Person的类型改成了interface.接口不能显式指定索引类型,这意味着您必须使用type.

如果你想使用interface,你需要添加一个像[key: string]: ...这样的索引签名,但我想这不是你想要的.因此,对于您的示例,您可能会坚持使用type.

更进一步,看看Record的定义.是type Record<K extends string | number | symbol, T> = { [P in K]: T; }.如果您定义的dataIndex没有symbol,则不能用keyof运算符覆盖它.因此,您需要在dataIndex的基础上加上symbol.我给你提供了一个例子.希望这能有所帮助.

type Person = {
    name: string;
    age: number;
}
type Recordable = Record<string, number | string | boolean>;
interface Column<T extends Recordable> {
    data: T;
    dataIndex?: string | number | symbol;
}
interface MyColumn<T extends Recordable> extends Column<T> {
    dataIndex: keyof T;
}
const jack: MyColumn<Person> = {
    data: { name: 'Jack', age: 1 },
    dataIndex: 'age',
};

编辑: Here是您的更新的固定示例

Typescript相关问答推荐

Angular 17 -如何在for循环内创建一些加载?

类型{...}的TypeScript参数不能赋给类型为never的参数''

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

在映射类型中用作索引时,TypeScrip泛型类型参数无法正常工作

类型{}上不存在属性&STORE&A;-MobX&A;REACT&A;TYPE脚本

如何根据特定操作隐藏按钮

编剧错误:正在等待Expect(Locator).toBeVisible()

如何解决类型T不能用于索引类型{ A:typeof A; B:typeof B;. }'

是否可以针对联合类型验证类型属性名称?

如何从输入中删除值0

专用路由组件不能从挂钩推断类型

自定义 Select 组件的类型问题:使用带逗号的泛型类型<;T与不带逗号的<;T&>;时出错

如何避免从引用<;字符串&>到引用<;字符串|未定义&>;的不安全赋值?

作为函数参数的联合类型的键

是否可以在类型脚本中定义条件返回类型,而不在函数体中使用类型转换?

如何在Angular /字体中访问API响应的子元素?

我可以将一个类型数组映射到TypeScrip中的另一个类型数组吗?

可以';t使用t正确地索引对象;联合;索引类型

如何在TypeScript中声明逆变函数成员?

如何向我的自定义样式组件声明 custom.d.ts ?