Type Checking Performance
In this page:
Core Concept
TypeScript's type checker can slow down noticeably on large codebases, especially with deeply nested generics, huge union types, or overly broad include globs that pull in files that don't actually need checking.
Example: Core Concept
// Deeply nested generics and huge unions slow down the type checker.
console.log("Large codebases can hit real type-checking performance limits");
Basic Setup
A basic diagnostic setup runs tsc --extendedDiagnostics (or --generateTrace) to see exactly which files and language features are consuming the most check time, rather than guessing at the bottleneck.
Example: Basic Setup
// tsc --extendedDiagnostics
console.log("extendedDiagnostics shows exactly what's consuming check time");
Typed Example
A typed example of a common slowdown: a union type with hundreds of string literal members forces the compiler to compare every member on each assignment check, which is measurably slower than a narrower type or an enum.
Example: Typed Example
type Status = "a" | "b" | "c"; // a 500-member union would be much slower
function check(s: Status) { return s; }
console.log(check("a"));
Project Usage
In a real project, splitting a monolith into project references (each independently cached) plus enabling "skipLibCheck": true are usually the two highest-impact changes for cutting overall check time.
Example: Project Usage
// tsconfig.json: { "compilerOptions": { "skipLibCheck": true } }
console.log("skipLibCheck plus project references are the biggest speed wins");
Best Practices
Avoid overly clever recursive conditional types in hot-path type definitions — they're a common, hard-to-spot source of exponential type-checking time on otherwise reasonably-sized codebases.
Example: Best Practices
// Avoid deeply recursive conditional types in hot-path type definitions.
type Depth1<T> = T extends string ? "string" : "other";
console.log("Recursive conditional types can cause exponential check time");
- Guessing at slow code without running
tsc --extendedDiagnosticsfirst. - Writing huge unions or deeply nested conditional types that slow the checker.
- Leaving
skipLibCheckoff in a big project, so.d.tsfiles innode_modulesare re-checked every time.
- Monorepos hold multiple packages in one repository, often sharing a types package.
- TypeScript project references and incremental compilation speed up building large projects.
- Type checking performance is worth attention as a project grows.
Chapter Quiz — Complete all 5 topics to unlock
0/5 topics done
Complete these topics first: