我有一个联合类型,每个子类型都有一个“类型”字段。我想自动构建一个类型,其字段是“ type”的不同值,并且这些值分别是相应子类型的数组。不知道这是否清楚,但是此示例会有所帮助:
// What I have :
type A = { type: "A" };
type B = { type: "B" };
type C = { type: "C" };
type MyUnion = A | B | C;
// What I want automatically generated :
type Keyed = {
A: A[];
B: B[];
C: C[];
};
是否有一种方法可以做到 而无需 ,只需给定A
即可手动将“ A”映射到类型MyUnion
等? / p>
我想到了类似的东西:
type Keyed = {
[T in MyUnion["type"]]: ??
};
但是我不知道如何基于MyUnion
将T
拆分为各个子类型。
答案 0 :(得分:1)
我认为这是做到这一点的方法:
type Keyed<T extends MyUnion> = {
[P in T["kind"]]: T extends (infer U)
? T["kind"] extends P
? U[] : never
: never
}
但是很复杂。也许手动编写Keyed
类更容易阅读。
需要使用束缚的extends
语句,因为您想不确定数组中没有不同类型的混合。例如,编译器会警告您这一点,因为在“ A”数组中有“ A”和“ B”类型:
var c: Keyed<MyUnion> = {
"A": [{ kind: "A" }, { kind: "B" }], // Error on 2nd item, bacause "B"
"B": [{ kind: "B" }],
"C": []
}
这是有效数据:
var c: Keyed<MyUnion> = {
"A": [{ kind: "A" }, { kind: "A" }],
"B": [{ kind: "B" }],
"C": []
}
我将属性type
重命名为kind
。它符合TypeScript文档中的约定,并避免了使用关键字type
作为属性名称的混淆。