将类型映射到字符串属性

时间:2020-10-29 23:00:07

标签: typescript

我有一堆数据类型都包含一个属性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与不是字符串的联合使用,并且在索引签名中使用方括号选择器感觉就像是拉伸。

是否可以根据所有数据类型都具有的属性来映射数据类型列表?

1 个答案:

答案 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;
}

Typescript Playground Link