Type narrowing refines types within conditional blocks. Here's how to use it effectively.
Basic Type Guards
Truthiness Narrowing
Equality Narrowing
in Operator Narrowing
Custom Type Guards
Discriminated Unions
Assertion Functions
Narrowing with Control Flow
Advanced Patterns
Best Practices
Type Guards:
✓ Use typeof for primitives
✓ Use instanceof for classes
✓ Use in for object properties
✓ Use discriminant for unions
Custom Guards:
✓ Return type predicate (is)
✓ Keep guards simple
✓ Throw for assertions
✓ Test edge cases
Control Flow:
✓ Use early returns
✓ Handle all union members
✓ Use never for exhaustiveness
✓ Be explicit about null
Avoid:
✗ Type assertions (as) instead of guards
✗ Complex nested conditions
✗ Ignoring null/undefined
✗ Assuming truthy means defined
Conclusion
TypeScript narrowing enables type-safe conditional logic. Use built-in type guards for common cases, custom type predicates for complex checks, and discriminated unions for state management. Always handle all union members and use exhaustiveness checking to catch missing cases.