TS2589 "Type instantiation is excessively deep": the generic builder that ate the compiler
verbatim errorerror TS2589: Type instantiation is excessively deep and possibly infinite.
# frequently with:
error TS2321: Excessive stack depth comparing types.
Problem
A type-safe query builder grew one feature too many and the compiler surrendered:
error TS2589: Type instantiation is excessively deep and possibly infinite.
# frequently with:
error TS2321: Excessive stack depth comparing types.tsc went from 9s to 3m40s, then started failing outright. Every IDE hover on the builder types spun the language server to 100% CPU.
Root cause
TS evaluates types eagerly at each use. Recursive generic chains (mapped types over mapped types over conditionals) instantiate exponentially: a DeepReadonly<T> over a 3-level schema is fine; a builder whose every chained method re-maps the entire accumulated type is O(2^n) in the number of chain steps. TS2589 is the compiler's recursion cap tripping — the type is not infinite, but the instantiation depth exceeded 50 (the internal limit).
fix preview — first 3 of 14 lines (ts), truncated:
// BEFORE: each .where() re-infers the entire accumulated query type
class Query<T, W> {
where<K extends keyof T>(k: K, v: T[K]): Query<T, W & Record<K, T[K]>> { ... }
… 11 more lines in the fix🔒 the fix — including 3 code blocks — is members-only. $1/mo unlocks everything.