1

Is it possible to define union type like this:

Union<T extends any[]> = // something...

and would be used like

Union<[string, number]> // would create (string | number)

I know I can immediatelly define union above, but I need it for usage in generics where it would end up being something like Union<[TDynamic, UDynamic]>

zhuber
  • 5,364
  • 3
  • 30
  • 63

1 Answers1

1

You can use the following type:

type Union<T extends any[]> = T extends (infer U)[] ? U : never;

This is actually basically the same type as Unpacked defined in the docs, and works because a type tuple becomes a type union in this case.

type X1 = Union<[number, string]>; // string | number
type X2 = Union<[number, number]>; // number
type X3 = Union<[number]>; // number

If you're on an older TypeScript version which does not support infer, you can also use:

type Union<T extends any[]> = T[number];
Ingo Bürk
  • 19,263
  • 6
  • 66
  • 100
  • Perfect, any way to be able to define like Union (to support dynamic number of generic arguments so I don't have to add array definition)? – zhuber Oct 06 '19 at 08:59
  • If you can write `Union`, why not write `T1 | T2` directly? I don't think for that you need a separate type. – Ingo Bürk Oct 06 '19 at 09:00
  • Because I'll use it in generic definition but I get your point, because I won't be able to pass it like that anyway in generic definition (will have array of dynamic types). One more question if you don't mind - is it possible to create Intersection type (same way as above Union)? – zhuber Oct 06 '19 at 09:04
  • 1
    You can possibly get that to work using @jcalz's `UnionToIntersection` trick: https://stackoverflow.com/a/50375286/1675492 – Ingo Bürk Oct 06 '19 at 09:11