Controllare se una tupla esaurisce un'unione in TypeScript
Nei tempi morti tra un task e l'altro, solitamente girovago tra i vari server di discord dedicati a TypeScript e do una mano nei canali d'aiuto. Questa è una domanda interessante che mi è capitata tra le mani:
È possibile creare un tipo Exhaustive<U,A> che controlli che ogni elemento dell'array A sia costitutivo dell'unione U e ogni costitutivo di U compaia esattamente una volta in A?
Ecco il mio tentativo:
type <, extends unknown[]> = [] extends [never]
? extends []
? true
: false
: extends [infer , ...infer ]
? extends
? <<, >, >
: false
: false;
Come suggerisce il nome, dobbiamo esaurire tutte le possibili coppie di elementi U-A, quindi le controlliamo tutte in maniera ricorsiva, rimuovendo le coppie già controllate ad ogni passo, fino a che l'array è vuoto e l'unione è 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']>
Non so quale possa essere il caso d'uso di un tipo del genere (chi ha posto la domanda non l'ha specificato), ma è stata comunque una sfida divertente.