Skip to content
webtype.orgwebtype.org

    ↑↓ move · ⏎ open · esc close

    No. 264 · September 16, 2026 · Moderate

    Everything but the first

    Implement Tail<T> so it produces the tuple T without its first element. An empty tuple stays empty.

    01

    Try the puzzle yourself

    Par 3

    Puzzle

    drop-first.ts
    Stroke 1 of 3Not run yet

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

    Checks

    3
    • Tail<[1, 2, 3]>—
      → [2, 3]
    • Tail<[1]>—
      → []
    • Tail<[]>—
      → []

    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 September 17, 2026

    The solution

    type Tail<T extends readonly unknown[]> = T extends [unknown, ...infer R] ? R : []

    The common wrong answer

    type Tail<T extends readonly unknown[]> = T extends [unknown, infer R] ? R : []

    Without the spread, [unknown, infer R] describes a tuple of exactly two elements and R is the second *element*, not the rest of the tuple. Tail<[1, 2, 3]> matches nothing and falls to []; Tail<[1, 2]> would return 2 — a number where a tuple was expected.

    Line by line

    1. [unknown, ...infer R]

      unknown in the head position matches any single element without naming it, and the spread makes R the remainder however long it is.

    2. : []

      The empty tuple has no head to remove, so it never matches the pattern and the fallback answers for it. Removing nothing from nothing is still nothing.

    Takeaway

    A spread in a tuple pattern is the difference between "the next one" and "all the others". Leaving it out silently changes what your pattern will even match.

    Uses