Skip to content

TypeScript diagnostic and refresher

Use this reference only for a demonstrated prerequisite gap. First explain or implement the relevant item without notes; after review, prove the repaired model in an Angular lesson.

Model finite states

Prefer unions over strings and boolean combinations:

type TopicStatus = 'not-started' | 'learning' | 'confident';

type LoadState<T> =
  | { status: 'loading' }
  | { status: 'success'; data: T }
  | { status: 'error'; message: string };

A switch on status narrows the available fields and can be checked exhaustively.

unknown before trust

External JSON, caught errors, and message events are not automatically domain objects. Use unknown, validate/narrow, then map. any disables the question.

Interfaces and readonly

Interfaces describe structural contracts. readonly prevents assignment through that reference but does not deep-freeze runtime objects. Immutable updates make signal notification and reasoning predictable.

Generics

LoadState<T> preserves the loaded data type. A generic should represent a relationship between types; do not add <T> merely to appear reusable.

Null safety

Handle missing route entities explicitly. Avoid ! unless an invariant truly exists outside TypeScript's knowledge and is enforced. Optional chaining is not a replacement for an intentional missing-data UI.

DOM event narrowing

An event handler receives Event; narrow at the boundary:

const value = (event.target as HTMLInputElement).value;

Better yet, reusable components can emit domain values so parents never see DOM event types.

Typed forms

Non-nullable controls prevent reset from introducing null. getRawValue() includes disabled controls; value may not. Form types protect client code, while runtime/server validation still protects system boundaries.

Verification challenge

Explain structural typing, covariance risks in mutable collections, never for exhaustiveness, type guard versus assertion, and compile-time type erasure at runtime using tracker examples. Then apply the weak item in typed forms or the HTTP trust boundary without a cast.