Search... ⌘K
Write Log In Sign Up

Join DevSolved

Share war stories & investigate outages.

Sign Up for Free Log In to Account
ESC
HIGH Resolved

TypeScript Type Instantiation: The Infinite Loop

Avatar Devsolved May 10, 2024 — 14:00 UTC MTTR: 3 hours 1 min read 115000 views
Executive Summary

A complex, deeply nested recursive generic type caused the TypeScript compiler (tsc) to run out of memory, completely blocking our CI/CD deployment pipeline.

The Symptom

Symptom

The GitHub Actions build step started failing randomly with `JavaScript heap out of memory`. When developers ran `npm run build` locally, their fans would spin up to maximum, and the process would eventually crash with `TS2589: Type instantiation is excessively deep and possibly infinite`.

Root Cause Analysis

Root Cause

A developer created a clever but overly complex recursive utility type to convert database snake_case keys into camelCase keys for the frontend (using Template Literal Types). While it worked fine for simple objects, when it was applied to a massive nested API response interface with recursive relationships, the TypeScript compiler tried to evaluate thousands of permutations, exhausting the V8 engine's memory.

Code typescript
// The fatal flaw: Recursive template literal types on deep structures
type SnakeToCamelCase<S extends string> = ...
type DeepCamelize<T> = T extends object ? {
    [K in keyof T as SnakeToCamelCase<K & string>]: DeepCamelize<T[K]>
} : T;

Resolution

Resolution

We removed the runtime-mimicking magic types. Instead of forcing the type system to compute camel casing, we explicitly defined the API response interfaces. We accepted that explicit interfaces are better than overly "clever" types that crash the compiler.

Preventive Action Items

high Remove DeepCamelize utility and strictly type API responses @Frontend Team
|

Discussions 0

Most recent