Check if a tuple exhausts a union in TypeScript
When I have a little time to spend in between some tasks, I usually wander on TS-related discord channels and lend a hand in helping channels. Here's a fun question I spent some time solving:
Is it possible to create a type Exhaustive<U, A> that checks that every element of the array A is a constituent of the union U and each constituent of U appears exactly once in A?
Here is my stab at it:
type <, extends unknown[]> = [] extends [never]
? extends []
? true
: false
: extends [infer , ...infer ]
? extends
? <<, >, >
: false
: false;
As the name suggests, we have to exhaust all the possible pairs U-A, so we're going to recursively check them all by removing the pairs from subsequent checks, until the array is empty and the union is never.
// Basic case
type = <'a'|'b'|'c', ['a','b','c']>
// Union and tuple have different order
type = <'a'|'b'|'c', ['b','c','a']>
// Duplicate element in array
type = <'a'|'b'|'c', ['a','a','b','c']>
// Shorter array
type = <'a'|'b'|'c', ['a','b']>
// Shorter tuple
type = <'a'|'b', ['a','b','c']>
While I don't know what use case this might serve (the original poster didn't mention it), this was a fun challenge nonetheless.