Skip to content
webtype.org#230 permutation · par 5

No. 230 · August 7, 2026 · Brutal

Permutation

Implement `Permutation<T>` so it turns a union into the union of every tuple ordering of its members. `never` has exactly one permutation: the empty tuple.

01

Try the puzzle yourself

Par 5

Puzzle

permutation.ts
Stroke 1 of 5Not run yet

Replace ??? — your solution is checked against the cases below. Tab indents; press Escape then Tab to move focus out.

Checks

4
  • Permutation<'a'>
    ['a']
  • Permutation<never>
    []
  • Permutation<'a' | 'b'>
    ['a', 'b'] | ['b', 'a']
  • Permutation<1 | 2>
    [1, 2] | [2, 1]

How a check is judged Exact type equality, not assignability — an intersection is not the same as the flattened object.

How everyone did

Fewer than 5 people have solved this one so far. The distribution appears once there is enough of a sample to mean anything.

Archive
02

Annotated solution

Published August 8, 2026

The solution

type Permutation<T, K = T> = [T] extends [never]
  ? []
  : K extends K
    ? [K, ...Permutation<Exclude<T, K>>]
    : never

The common wrong answer

type Permutation<T> = T extends T ? [T] : never

This distributes and wraps each member in its own tuple, giving `["a"] | ["b"]` — every member alone, never combined. It also answers `never` for `never`, because distributing over the empty union produces nothing rather than the empty tuple.

Line by line

  1. [T] extends [never]

    The tuple wrapper suppresses distribution, which is essential here: a distributive conditional over `never` produces `never` and the base case would never be reached.

  2. K extends K

    A conditional that is trivially true, used purely for its side effect: it distributes `K` so the branch below runs once per union member. `K` defaults to `T`, keeping an untouched copy while `T` is narrowed by `Exclude`.

Takeaway

`K extends K` is the idiom for "distribute this union" and `[T] extends [never]` is the idiom for "do not". Knowing both, and which one a line needs, is most of what separates working type-level code from code that silently returns `never`.