Понадобилось по работе собрать из union список туплов со всеми возможными перестановками. То есть, чтобы из "a" | "b" получалось ["a"] | ["b"] | ["a", "b"] | ["b", "a"]. Написал в лоб решение на 15 строк и подумал, что это как-то дофига. Начал ковырять плейграунд и пытаться соптимизировать.

Дооптимизировал до одной строки, и полчаса сам вкуривал, как это работает:

// Все перестановки в union
type Permutations<T, U = T> = T extends U ? [ T ] | [ T, ...Permutations<Exclude<U, T>> ] : never;

type Test = Permutations<'a' | 'b'>; // ["a"] | ["b"] | ["a", "b"] | ["b", "a"]

Всё время я про эту фичу забываю. Запишу-ка тут, чтобы потом было где подсмотреть.

Магия происходит из-за того, что вот такая конструкция T extends U ? [ T ] : never, раскладывается на юнион из кортежей. То есть, в качестве T, в результате тернарного extends, будет по очереди подставлено каждое значение из пересечения T и U:

type Test<T, U = T> = T extends U ? [ T ] : never;
type Test2 = Test<'a' | 'b'>; // ["a"] | ["b"]

Ну, а дальше уже понятно.