Control-Flow Narrowing
TypeScript tracks checks such as typeof, equality comparisons, in, instanceof, and early returns to refine a variable's type along a control-flow path. This is called narrowing. It is usually better to narrow using a real runtime fact than to force a type assertion.
For object unions, checking a property or a discriminant can identify the current variant. Be careful with optional properties and overlapping object shapes: a check is only as strong as the runtime fact it establishes.
Narrow an unknown input
function describe(value: string | number): string {
if (typeof value === "number") {
return value.toFixed(1);
}
return value.toUpperCase();
}💡 Inside the first branch
value is a number; after the return, the remaining path is a string. TypeScript follows the control flow to determine the safe type.Key Takeaways
- Runtime checks can narrow unions.
- Early returns often simplify the remaining type.
- Assertions do not perform runtime validation.
Knowledge Check
After `if (typeof value === "number")`, what is the type of `value` inside that branch for `string | number`?