让我们从这个给定的类型开始:
type Union =
{ type: 'A', a: string } |
{ type: 'B', b: number }
我希望我们在这里结束:
type MappedUnion = {
A: { type: 'A', a: string }
B: { type: 'B', b: number }
}
这是一些伪代码:
type MappedUnion<item in Union> = {[ i: item['type'] ]: item}
答案 0 :(得分:1)
我认为你可以做到以下几点? Haven没有详尽地测试过,但似乎有效。
type Union =
{ type: 'A', a: string } |
{ type: 'B', b: number }
type MappedUnion = {[P in Union['type']]: Union & {type: P}};
const v: MappedUnion = {
'A': {type: 'A', a: "hello"},
'B': {type: 'B', b: 3},
}
可悲的是,没有相当的工作;如果我做
type MappedUnionTarget = {
A: { type: 'A', a: string }
B: { type: 'B', b: number }
}
function cvt1(x: MappedUnion): MappedUnionTarget {
return x;
}
然后我得到Type '({ type: "A"; a: string; } & { type: "A"; }) | ({ type: "B"; b: number; } & { type: "A"; })' is not assignable to type '{ type: "A"; a: string; }'.
我认为打字稿能够得出结论({ type: "B"; b: number; } & { type: "A"; })
与never
相同。
如果您愿意使用Typescript 2.8(在撰写本文时,如果您使用TypeScript存储库中的git pull
并且支持条件运算符? :
,那么它是未发布的在类型级别)然后你似乎可以做
type FilterType<T, K> = (T extends { type: K } ? T : never);
type MappedUnion = {[P in Union['type']]: FilterType<Union, P>};
因为FilterType<T, K>
是我希望T & {type: K}
表现得像的事情。