TypeScript:从有区别的联合派生地图 [英] TypeScript: derive map from discriminated union
问题描述
我有一个区分的联合类型,该类型根据字符串文字字段来区分类型.我想派生一个映射类型,该映射类型将并集中的所有类型映射到其相应的鉴别符文字值.
I have a discriminated union type that differentiates types based on a string literal field. I would like to derive a mapped type that maps all of the types in the union to their corresponding discriminator literal values.
例如
export type Fetch = {
type: 'fetch',
dataType: string
};
export type Fetched<T> = {
type: 'fetched',
value: T
};
// union type discriminated on 'type' property
export type Action =
| Fetch
| Fetched<Product>;
// This produces a type 'fetch' | 'fetched'
// from the type
type Actions = Action['type'];
// I want to produce a map type of the discriminator values to the types
// comprising the union type but in an automated fashion similar to how I
// derived my Actions type.
// e.g.
type WhatIWant = {
fetch: Fetch,
fetched: Fetched<Product>
}
在TypeScript中可以吗?
Is this possible in TypeScript?
推荐答案
With the introduction of conditional types in TypeScript 2.8, you can define a type function which, given a discriminated union and the key and value of the discriminant, produces the single relevant constituent of the union:
type DiscriminateUnion<T, K extends keyof T, V extends T[K]> =
T extends Record<K, V> ? T : never
如果您想使用它来构建地图,也可以这样做:
And if you wanted to use that to build up a map, you can do that too:
type MapDiscriminatedUnion<T extends Record<K, string>, K extends keyof T> =
{ [V in T[K]]: DiscriminateUnion<T, K, V> };
所以在您的情况下,
type WhatIWant = MapDiscriminatedUnion<Action, 'type'>;
如果您对其进行检查,则为:
which, if you inspect it, is:
type WhatIWant = {
fetch: {
type: "fetch";
dataType: string;
};
fetched: {
type: "fetched";
value: Product;
};
}
我认为是所希望的.希望能有所帮助;祝你好运!
as desired, I think. Hope that helps; good luck!
这篇关于TypeScript:从有区别的联合派生地图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!