Issue
If the discrimated union is defined as follows:
enum KEYS {
A= 'a',
B= 'b'
...
}
type TUnion =
| { keyType: KEYS.A; items: AType[]
| { keyType: KEYS.B; items: BType[]
...
How can I define the type for an object where the key is a keyType
and the value is the matching ìtems`, without doing it all manually?
The manual approach seems to work but repeats the key-to-possible values relation:
type TObj = {
[KEYS.A]?: AType[]
[KEYS.B]?: BType[]
...
}
Solution
Here's a great utility type to take a discriminated union and two of its properties and transform it into a map of the keys to values:
type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (k: infer I) => void ? { [K in keyof I]: I[K] } : never;
type FromDiscriminatedUnion<U, K extends keyof U, V extends keyof U> = UnionToIntersection<U extends U ? {
[_ in U[K] & PropertyKey]: U[V];
} : never>;
We distribute over the union and get the selected key and map it to a value. Since this produces another union, we need to turn this union into an intersection.
Lastly, if you want all the properties to be optional, wrap the output with Partial
:
type Result = Partial<FromDiscriminatedUnion<TUnion, "keyType", "items">>;
Answered By - caTS
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.