Mental model
In strict mode (strictNullChecks: true), null and undefined are distinct domain types, eliminating Tony Hoare's "billion-dollar mistake" of unhandled null pointer dereferences.
Theory
TypeScript's control flow engine tracks variable assignments, truthiness checks, equality guards, and custom type predicates (value is User). Custom assertion functions (asserts condition) narrow types in the calling scope by throwing an error if the condition evaluates to false.
Alternatives and trade-offs
- Non-null assertion operator (
!): Tells TypeScriptvalue!is non-null without checking. Risky; throws runtimeTypeErrorif wrong. - Explicit Type Guards (
isDefined): Type-safe runtime check that narrows types automatically.
Failure modes and misconceptions
||vs??Operator: The logical OR operator (||) falls back on falsy values ("",0,false). Nullish coalescing (??) falls back ONLY onnullorundefined.- Abusing
!assertion: Usinguser!.emailbypasses type checking without runtime protection.
Decision scenario
Use nullish coalescing (??) when providing fallbacks for missing API string or numeric fields. Avoid the non-null assertion operator (!) in production application code.
Learning outcomes
- Configure
strictNullChecksto eliminate unhandled null pointer bugs. - Implement custom type predicates (
val is T) for collection filtering. - Author scope-narrowing assertion functions (
asserts val is T).
Trade-offs
Strict null checking prevents runtime null reference exceptions, but requires explicit guards or default fallbacks whenever handling optional network data.