Annotated solution
Published September 3, 2026The solution
type Fill<N extends number, V, R extends V[] = []> = R['length'] extends N ? R : Fill<N, V, [...R, V]>
The common wrong answer
type Fill<N extends number, V, R extends V[] = []> = R['length'] extends N ? R : [...R, V]
This adds one element and then stops. The `else` branch has to call `Fill` again — appending is the step, not the answer. Written this way, `Fill<3, "x">` returns `["x"]`, because the type ran exactly once.
Line by line
R['length'] extends N ? R : ...The accumulator is also the counter. A tuple knows its own length, so there is no arithmetic to do — just ask whether it has reached `N` yet.
Fill<N, V, [...R, V]>Each recursion hands the next call a slightly longer tuple. `Fill<0, number>` never enters this branch at all, because an empty accumulator already has the requested length.
Takeaway
An accumulator parameter turns a recursive type into a loop with a variable. The base case is a question about the accumulator, and the step is the same type called with a bigger one.

