Concept 11 of 12
Variadic tuples
Tuples are the type level’s only data structure with a length, which makes them its only counter. Every piece of type-level arithmetic you will ever see is counting elements in a tuple wearing a disguise.
Spreads concatenate
type A = [1, 2] type B = [3, 4] type Joined = [...A, ...B] // [1, 2, 3, 4] type Prefixed = [0, ...A] // [0, 1, 2] type Len = Joined['length'] // 4 — a numeric literal type
For a fixed-length tuple, `length` is a numeric literal rather than `number`. That single fact is what makes arithmetic possible: build a tuple of the right size, then read its length back out.
Addition is concatenation, subtraction is matching
type Build<N extends number, Acc extends unknown[] = []> = Acc['length'] extends N ? Acc : Build<N, [...Acc, unknown]> type Add<A extends number, B extends number> = [...Build<A>, ...Build<B>]['length'] type Sub<A extends number, B extends number> = Build<A> extends [...Build<B>, ...infer Rest] ? Rest['length'] : never
Building a tuple adds; taking one apart subtracts. The accumulator holds `unknown` because its contents are irrelevant — it is a tally of marks, not a collection of anything.
A rest element need not be last
type Last<T> = T extends readonly [...unknown[], infer L] ? L : never type Init<T> = T extends readonly [...infer I, unknown] ? I : never
A tuple pattern may contain exactly one rest element, and it is allowed at the front. That is how you reach the end of a tuple without counting your way there.
The common wrong answer
// Intent: subtract. type Sub<A extends number, B extends number> = [...Build<A>, ...Build<B>]['length'] // That is addition with a different name — concatenating // can only ever make the tuple longer.
Subtraction has to take a tuple apart, which means pattern matching rather than building. If your arithmetic type only ever spreads, it can only ever add.
Exercise
Add an element to the front of a tuple.
Try it
2Unshift<[2, 3], 1>—→ [1, 2, 3]Unshift<[], 'a'>—→ ['a']
Takeaway
Tuple length is the only number the type system can count with. Build to add, destructure to subtract, and expect the recursion limit around a thousand.

