Skip to content
webtype.orgwebtype.org#223 type-level-subtract · par 5

    ↑↓ move · ⏎ open · esc close

    No. 223 · July 31, 2026 · Brutal

    Type-level Subtract

    Implement `Subtract<A, B>` returning `A − B` as a number literal. When `B` is larger than `A` the answer is `never` — there are no negative tuple lengths.

    01

    Try the puzzle yourself

    Par 5

    Puzzle

    type-level-subtract.ts
    type BuildTuple<N extends number, Acc extends unknown[] = []> =
      Acc['length'] extends N ? Acc : BuildTuple<N, [...Acc, unknown]>
    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
    • Subtract<5, 3>
      2
    • Subtract<3, 3>
      0
    • Subtract<10, 4>
      6
    • Subtract<2, 5>
      never

    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.

    Short game

    Fewest characters

    No public scores yet.

    Archive
    02

    Annotated solution

    Published August 1, 2026

    The solution

    type Subtract<A extends number, B extends number> =
      BuildTuple<A> extends [...BuildTuple<B>, ...infer Rest] ? Rest['length'] : never

    The common wrong answer

    type Subtract<A extends number, B extends number> =
      [...BuildTuple<A>, ...BuildTuple<B>]['length']

    That is addition wearing a different name. Concatenating the two tuples can only ever make them longer; subtraction has to take a tuple *apart*, which means pattern-matching rather than building.

    Line by line

    1. [...BuildTuple<B>, ...infer Rest]

      The pattern hard-codes a prefix of exactly `B` elements and lets `Rest` absorb whatever is left. Matching succeeds only when the subject is at least that long.

    2. : never

      When `B > A` there is no way to line up the prefix, the conditional fails, and `never` falls out — which is the honest answer for a subtraction this arithmetic cannot represent.

    Takeaway

    Building tuples adds; destructuring them subtracts. Every arithmetic operation TypeScript can do at the type level is one of those two motions in disguise.

    Uses