All glossary terms
Optimize

Type narrowing

Type narrowing is TypeScript's ability to refine a value's type within a conditional branch based on runtime checks — typeof, instanceof, in operator, equality checks, custom type predicates. Narrowing lets a parameter typed as 'string | number' be treated as a string inside a 'typeof x === string' branch without explicit casts.

Narrowing is the everyday workhorse of TypeScript ergonomics: it's what makes union types pleasant to work with. The narrowing operators are: typeof for primitives, instanceof for class instances, in for property existence checks, equality for literal types, and user-defined type predicates ('x is Foo') for arbitrary refinements. Modern TypeScript narrows aggressively: control-flow analysis tracks assignments, early returns narrow the rest of the function, and discriminated unions narrow via the discriminant check. When narrowing doesn't kick in, the cause is usually mutable state (the type system can't prove the narrowed type still holds after a function call) or a missing discriminant.

Related terms