typescript - 在 Typescript 中键入键值对对象并保存对象的键

标签 typescript

我在下面的例子中有键值对对象


interface ItemType {
    a: number;
    b: string;
}

const list = {
    first: {a: 1, b: 'one'},
    second: {a: 2, b: 'two'},
    third: {a: 3, b: 'three'},
} as { [key in keyof typeof list]: ItemType }

但它会引发错误,例如 TS2313: Type parameter 'key' has a circular constraint.

我希望所有项目都是 ItemType 类型,但仍希望列表保存我插入的键。如果我将它转换为 { [key in string]: ItemType },我将丢失列表的键名。 :(

最佳答案

如果您想验证某个值是否可分配给某个类型而不扩大到该类型并可能丢弃您关心的信息,您可以使用辅助标识函数,如下所示:

const itemDict = <K extends PropertyKey>(dict: { [P in K]: ItemType }) => dict;

这里 itemDict() 应该只接受一个你正在寻找的类型的对象作为参数:它的键是任何类似键的 K extends PropertyKey 这将调用时由编译器推断,其属性为 ItemType。因为键集 K 是类型的一部分,所以不会被遗忘:

const list = itemDict({
  first: { a: 1, b: 'one' },
  second: { a: 2, b: 'two' },
  third: { a: 3, b: 'three' },
});

list.second.a.toFixed(); // okay

list.fourth; // error!
// Property 'fourth' does not exist on type 
// '{ first: ItemType; second: ItemType; third: ItemType; }'

请注意,list 由编译器根据需要推断为类型 {first: ItemType, second: ItemType, third: ItemType}

Playground link to code

关于typescript - 在 Typescript 中键入键值对对象并保存对象的键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66326903/

相关文章:

javascript - 我们可以在 Typescript 声明文件中使用全局符号吗?

javascript - 如何使用 Angular 1.x 和 Typescript 设置 Webpack 以使用 Angular 模板(ng-include)?

android - ionic 3 native : File : {code: 5, 消息: "ENCODING_ERR"}

javascript - 如何将 event.target 作为 Angular 2 中的对象获取?

angular - 来自另一个 Controller 的 ionic 2 调用函数

javascript - Typescript import index.ts 不是一个模块

json - 通过 JSON 的 Angular 2 路由映射

typescript - 使用变量的类型作为另一个 typescript 的类型

angular - 类型 'find' 上不存在属性 'FormGroup'。任何

angular - 如何用 Angular 制作通用解析器 (2+)