Skip to content
webtype.orgwebtype.org#244 repeat-string · par 4

    ↑↓ move · ⏎ open · esc close

    No. 244 · August 27, 2026 · Hard

    Repeat

    Implement `Repeat<S, N>` so it concatenates the string `S` exactly `N` times. Repeating zero times gives the empty string.

    01

    Try the puzzle yourself

    Par 4

    Puzzle

    repeat-string.ts
    Stroke 1 of 4Not run yet

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

    Checks

    4
    • Repeat<'ab', 3>
      'ababab'
    • Repeat<'x', 0>
      ''
    • Repeat<'x', 1>
      'x'
    • Repeat<'-', 5>
      '-----'

    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 28, 2026

    The solution

    type Repeat<
      S extends string,
      N extends number,
      Acc extends unknown[] = [],
    > = Acc['length'] extends N ? '' : `${S}${Repeat<S, N, [...Acc, unknown]>}`

    The common wrong answer

    type Repeat<
      S extends string,
      N extends number,
      Acc extends unknown[] = [],
    > = Acc['length'] extends N ? S : `${S}${Repeat<S, N, [...Acc, unknown]>}`

    The base case emits one copy too many. Returning `S` when the counter is full means the terminating step also contributes, so `Repeat<"ab", 3>` produces four copies — and `Repeat<"x", 0>` returns `"x"` when it should return nothing at all.

    Line by line

    1. Acc['length'] extends N ? ''

      The base case must be the *identity* of the operation being built. For concatenation that is the empty string, exactly as `[]` is the base case when building a tuple and `0` would be when adding numbers.

    2. [...Acc, unknown]

      The accumulator holds `unknown` because its contents are irrelevant — only its length is being read. It is a tally, not a collection.

    Takeaway

    Whenever a type-level loop is off by one, look at what the base case returns rather than at the recursive step. The terminating branch should contribute the neutral element, not another copy of the payload.

    Uses