Skip to content

    ↑↓ move · ⏎ open · esc close

    TS2456

    Circular type alias

    Type alias 'Loop' circularly references itself.

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

    The alias is defined in terms of itself with nothing in between, so there is no point at which it means anything.

    Reproduction

    type Loop = Loop

    The build asserts this emits exactly this code.

    Why the compiler says this

    A recursive type is fine — the archive is full of them — but the recursion has to pass through something that defers it: an object property, an array element, a conditional branch that can stop. A bare self-reference has no such step, so there is nothing to expand and nothing to terminate. The compiler is not refusing recursion; it is pointing out that this is not recursion, it is a definition that eats itself.

    Fixes

    1. 01
      type Loop = { next: Loop }
      
      declare const chain: Loop
      const deep = chain.next.next

      Put the reference behind a property. Object types are lazy, so `Loop` inside `{ next: … }` is only expanded when something reaches for it.

    2. 02
      type Nested<T> = T extends [infer Head, ...infer Rest] ? Head | Nested<Rest> : never
      
      type Flat = Nested<[1, 2, 3]>

      Or recurse through a conditional that can reach a base case. Each step here removes an element, so the expansion is guaranteed to stop.

    Takeaway

    Recursion needs somewhere to pause and somewhere to stop. An alias that names only itself has neither.

    Where to go next

    Errors