Skip to content

Instantly share code, notes, and snippets.

@betafcc
Last active February 1, 2020 10:36
Show Gist options
  • Save betafcc/7e6531a0fd48ce30a00cb9ace68b821d to your computer and use it in GitHub Desktop.
Save betafcc/7e6531a0fd48ce30a00cb9ace68b821d to your computer and use it in GitHub Desktop.
Typescript Union to all Union of Tuples possible with it's elements
// UnionToTuple<1 | 2 | 3> -> [3, 2, 1] | [2, 3, 1] | [3, 1, 2] | [1, 3, 2] | [2, 1, 3] | [1, 2, 3]
type UnionToTuple<U> = _UnionToTuple<U, []>[0]
type _UnionToTuple<U, L extends Array<U>> = Done<U, L> extends true
? [L] // boxing prevents circulatory reference
: [_UnionToTuple<U, ConsDistinct<U, L>>[0]]
// ConsDistinct<(1 | 2), ([1] | [2] | [3])> -> [1, 2] | [1, 3] | [2, 1] | [2, 3]
type ConsDistinct<A, L extends Array<unknown>> = L extends any
? A extends any
? A extends L[number]
? never
: Parameters<(a: A, ...l: L) => any>
: never
: never
// Check if every tuple in L has all the elements of U
type Done<U, L extends Array<unknown>> = L extends any
? [U] extends [L[number]]
? true
: false
: never
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment