Skip to content

    ↑↓ move · ⏎ open · esc close

    TS2589

    Excessively deep

    Type instantiation is excessively deep and possibly infinite.

    The compiler’s own words. Not translated — this is the string you pasted into a search box.

    A recursive type went further than the compiler is willing to follow — usually around fifty levels, and almost always because the recursion is counting rather than shrinking.

    Reproduction

    type Repeat<S extends string, N extends number, A extends unknown[] = []> =
      A['length'] extends N ? S : Repeat<`${S}x`, N, [...A, unknown]>
    
    type Long = Repeat<'a', 1000>

    The build asserts this emits exactly this code.

    Why the compiler says this

    TypeScript puts a hard ceiling on how many times a type may instantiate itself, because a type that recurses forever would hang the compiler rather than fail it. The limit is not a bug and it is not tunable. Reaching it means the recursion is doing arithmetic — one step per unit — and the only fix that scales is to make each step remove more work than it adds.

    Fixes

    1. 01
      type Repeat<S extends string, N extends number, A extends unknown[] = []> =
        A['length'] extends N ? S : Repeat<`${S}x`, N, [...A, unknown]>
      
      type Short = Repeat<'a', 12>

      Stay under the ceiling. If the input is genuinely small — a path with four segments, a tuple with ten members — the counting recursion is fine and the honest fix is to stop asking it for a thousand.

    2. 02
      type Repeat<S extends string, N extends number> = N extends 0 ? '' : string
      
      type Wide = Repeat<'a', 1000>

      Or give up the precision. A type that returns `string` for anything large is less informative and infinitely cheaper, and for a value nobody reads character by character that is usually the right trade.

    Takeaway

    This error is almost never solved by restructuring the recursion. It is solved by wanting less: a smaller input, or a vaguer answer.

    Where to go next

    Errors