1

I can get all keys of a union by type UnionKeys<T> = { [Key in keyof T]: Key }[keyof T]

type MyUnion = {x: 'a', y: 'b'} |  {x: 'aa', z: 'c'}
type T1 = UnionKeys<MyUnion> // 'x' | 'y' | 'z'

How do I get the merged type of a union?

type MergedUnion<T> = ?????
type T2 = MergedUnion<MyUnion> // `{x: 'a' | 'aa', y: 'b', z: 'c'}`
Jacob
  • 1,642
  • 2
  • 15
  • 27

1 Answers1

2

This can be done. We map over UnionKeys ( I used a different definition, using distributive conditional types) and we use another distributive conditional type to extract a union of all values that a specific key can have:

type MyUnion = {x: 'a', y: 'b'} |  {x: 'aa', z: 'c'}
type UnionKeys<T> = T extends unknown ? keyof T : never;
type UnionValues<T, K extends PropertyKey> = T extends Record<K, infer U> ? U: never;
type MergedUnion<T> = { [P in UnionKeys<T>]: UnionValues<T, P> }
Titian Cernicova-Dragomir
  • 230,986
  • 31
  • 415
  • 357
  • Nice! Could you explain why `T extends unknown ? keyof T : never` behaves differently than regular `keyof T`? – Aleksey L. Apr 27 '19 at 07:59
  • 1
    @AlekseyL. Because of distributive conditional types, you can read here https://stackoverflow.com/questions/51651499/typescript-what-is-a-naked-type-parameter/51651684#51651684. I'm sorry I've written up the explanation for distribution so many times my fingers rebel at the very thought of writing it again :)). – Titian Cernicova-Dragomir Apr 27 '19 at 08:03