Combination
Less than 1 minuteTC-Medium
Combination
Problem
Given an array of strings, do Permutation & Combination.
It's also useful for the Vuex binding helpers.
type Keys = Combination<['foo', 'bar', 'baz']>
// 'foo' | 'bar' | 'baz' | 'foo bar' | 'foo baz' | 'bar baz' | 'foo bar baz' ...Solution
Approach: Union Distribution with Exclusion
Convert the array to a union, then for each element, combine it with all sub-combinations of the remaining elements.
type Combination<T extends string[], U extends string = T[number]> =
U extends string
? U | `${U} ${Combination<[], Exclude<U, U>> }` | `${U} ${string & Exclude<T[number], U>}`
: neverA cleaner version:
type Combination<
T extends string[],
All extends string = T[number],
U extends string = All
> = U extends All
? U | `${U} ${Combination<[], Exclude<All, U>>}`
: neverHow it works:
T[number]converts the tuple to a string unionAll.- Distribute over each member
UofAll. - For each
U, produceUalone orUfollowed by space and a combination of the remaining items. Exclude<All, U>removes the current item to avoid repeats.
Key Takeaways
- Converting a tuple to a union with
T[number]is often the first step in combination/permutation problems. - The recursive call uses
Excludeto shrink the available set — "choose each item at most once". - Distributing over a union with
U extends Allgenerates all possible choices in parallel.
