以下是TypeScrip中的类型定义:

interface Obj {
id:string
}

我想定义一个名为ObjCollection的Obj集合,其中ObjCollection的索引必须与id字段相同.

const objcollection: ObjCollection = {
  key1: { id: "key1" },
  key2: { id: "key2" },
  key3: { id: "key33333" } // Error, id should be key3
}

那么,应该如何定义ObjCollection呢?

推荐答案

Typescript 中没有符合您要求的特定ObjCollection类型.相反,您可以像这样定义一个generic类型

type ObjCollection<K extends PropertyKey> =
    { [P in K]: { id: P } }

它表达了这一思想,但它取决于提供与一组键相对应的类型参数.所以你的objcollection应该是ObjCollection<"key1" | "key2" | "key3">类型的.为了避免您自己编写该代码,您可以编写一个通用的助手函数,让编译器进行推断:

const asObjCollection = <K extends PropertyKey>(
    oc: ObjCollection<K>) => oc;

然后,你会写const objcollection = asObjCollection({⋯}),而不是写const objcollection: ObjCollection = {⋯}.它不一样,但很接近,它给了你想要的行为:

const objcollection = asObjCollection({
    key1: { id: "key1" },
    key2: { id: "key2" },
    key3: { id: "key33333" } // error!
});

Playground link to code

Typescript相关问答推荐

React-Native运行方法通过监听另一个状态来更新一个状态

带有联合参数的静态大小数组

属性的类型,该属性是类的键,其值是所需类型

在TypeScript中,除了映射类型之外还使用的`in`二进制运算符?

具有动态键的泛型类型

Angular 错误NG0303在Angular 项目中使用app.Component.html中的NGFor

不推荐使用Marker类-Google map API警告

ANGLE找不到辅助‘路由出口’的路由路径

在不更改类型签名的情况下在数组并集上映射文字

在保留类型的同时进行深层键名转换

为什么&Quot;元素隐式具有';Any';类型,因为...即使我已经打字了,也不能作为索引显示错误吗?

在正常函数内部调用异步函数

类型判断数组或对象的isEmpty

如何在Vue动态类的上下文中解释错误TS2345?

我如何键入它,以便具有字符串或数字构造函数的数组可以作为字符串或数字键入s或n

将带有额外id属性的Rust struct 展平回TypeScript单个对象,以返回wasm-bindgen函数

在ts中获取级联子K类型?

断言同级为true或抛出错误的Typescript函数

为什么 TypeScript 类型条件会影响其分支的结果?

将函数签名合并到重载中