Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Typescript, how to turn a discrimated union into an object?

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:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

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">>;

Playground

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading