我有一堆数据类型都包含一个属性dataType
,我将每个映射到该值:
interface GroupData {
dataType: "group";
name: string;
people: PersonData[];
}
interface PersonData {
dataType: "person";
name: string;
email: string;
messages: MessageData[];
}
interface MessageData {
dataType: "message";
message: string;
timestamp: number;
}
interface DataTypeMap {
group: GroupData;
person: PersonData;
message: MessageData;
}
这符合我的目的,但是有点手动。在我的实际应用程序中,我有很多个数据类型,它们的更改频率有些高。我想要的是能够使该过程自动化一些。到目前为止,这与我来的差不多:
type DataType = GroupData
| PersonData
| MessageData;
type DataTypeMap = {
[(T in DataType)["dataType"]]: T;
};
对单个数据类型联合进行审核要比映射(键必须具有特定值)容易得多。 但是这不是TypeScript中的犹太洁食。我收到以下TS错误:
A computed property name in a type literal must refer to an expression whose type is a literal type or a 'unique symbol' type.
Cannot find name 'T'.
'DataType' only refers to a type, but is being used as a value here.
据我所知,这些都是我的语法问题。我90%肯定不能将in
与不是字符串的联合使用,并且在索引签名中使用方括号选择器感觉就像是拉伸。
是否可以根据所有数据类型都具有的属性来映射数据类型列表?
答案 0 :(得分:1)
您是如此亲密!这就是我们想要的:
type DataTypeMap = {
[T in DataType['dataType']]: Extract<DataType, {dataType: T}>;
};
DataType
是所有类型接口的并集。 DataType['dataType']
是所有类型名称字符串文字的并集。
在我们的地图上,我们说这些键是那些string
名称。对于每个键,我们想要找到对应的interface
。我们使用Extract
来获取可以拥有{dataType: T}
的联合会成员。
此解析为:
type DataTypeMap = {
group: GroupData;
person: PersonData;
message: MessageData;
}