4

Given a type 'a' | 'b' | 'c', if and how is it possible to generate the type ['a', 'b', 'c']?

Mateja Petrovic
  • 3,799
  • 4
  • 25
  • 40
  • See [the answer](https://stackoverflow.com/a/55128956/2887218) to the linked question; there is no way to guarantee order of the resulting tuple, since `'a' | 'b' | 'c'` is the same type as, for example, `'c' | 'a' | 'b'` and it's an implementation detail of the compiler what order it uses internally. – jcalz Oct 14 '21 at 16:05

1 Answers1

4

UnionToTuple convert every union to tuple.
In your case UnionToTuple<'a' | 'b' | 'c'> will create ['a', 'b', 'c'] type

// UnionToIntersection<A | B> = A & B
type UnionToIntersection<U> = (
  U extends unknown ? (arg: U) => 0 : never
) extends (arg: infer I) => 0
  ? I
  : never;

// LastInUnion<A | B> = B
type LastInUnion<U> = UnionToIntersection<
  U extends unknown ? (x: U) => 0 : never
> extends (x: infer L) => 0
  ? L
  : never;

// UnionToTuple<A, B> = [A, B]
type UnionToTuple<T, Last = LastInUnion<T>> = [T] extends [never]
  ? []
  : [Last,...UnionToTuple<Exclude<T, Last>>]

Typescript playground

P.S.: Found this and many useful typescript generic types in Typescript challanges

Mike Kokadii
  • 509
  • 5
  • 17
  • 1
    I love [the challenges you linked to](https://github.com/type-challenges/type-challenges), had never seen that – Ruan Mendes Oct 14 '21 at 13:37
  • You cannot guarantee that `'a' | 'b' | 'c'` becomes `['a', 'b', 'c']`. Ordering of unions is an implementation detail of the compiler. See [this link](https://tsplay.dev/mLRkAw) and see what happens if you uncomment the line with `SomethingElsewhere` in it. – jcalz Oct 14 '21 at 16:09
  • Did you guys find any solution for fixing the ordering of the unions? – Nazar Hussain Jan 19 '22 at 21:23
  • 1
    @NazarHussain there is [one answer](https://stackoverflow.com/a/55128956/13781208) to another similar question that kinda working but it is do not recommended to use it. – Mike Kokadii Jan 26 '22 at 18:32