Concept lesson

Advanced TypeScript Types

Generics, discriminated unions, conditional types, and infer type mechanics.

lesson
Freshness: current14 min read
Mastery
not started · 0%

Learning outcomes

  • Master generic constraints and discriminated unions
  • Implement infer conditional type extractions

Mental model

TypeScript's type system is structural, set-theoretic, and erased at compile time. Types represent sets of values, where unknown is the universal set and never is the empty set.

Generic type parameter T
Constraint T extends Record
Discriminated tag literal
Infer conditional type
Compiled erased JS payload
Conceptual teaching model synthesized from:TypeScript 5.4 Language Specification & Type System Mechanics

Theory

Generic constraints (T extends K) restrict type parameter bounds. Discriminated unions leverage literal tag fields (type: 'success' | 'error') to enable control-flow type narrowing across switch/if statements. Conditional types (T extends U ? X : Y) combined with the infer keyword extract nested type signatures at compile time.

export type APIResponse<T> =
  | { status: "success"; data: T; timestamp: number }
  | { status: "error"; error: { code: string; message: string }; timestamp: number };

export type ExtractData<T> = T extends { status: "success"; data: infer D } ? D : never;

export function handleResponse<T>(res: APIResponse<T>): T | null {
  if (res.status === "success") {
    return res.data;
  }
  console.error(`[${res.error.code}]: ${res.error.message}`);
  return null;
}

Alternatives and trade-offs

Nominal type systems (like C++ or Java) enforce type equivalence by name, whereas TypeScript enforces structural compatibility. Over-engineering deeply nested conditional types increases compiler check time (tsc --noEmit). Keep utility types shallow and explicit.

Failure modes and misconceptions

  1. any bypass: Using any disables all type-checking safety. Use unknown for unchecked external data.
  2. Runtime type assumptions: TypeScript types do NOT exist at JS runtime. Always validate incoming network JSON with runtime schemas (Zod/Pydantic).
  3. Type assertions (as T): Overriding compiler inference with as conceals runtime bugs.
Reflect before revealing the guide

Decision scenario

When designing client-server event contracts, use discriminated unions with explicit tag literals. Avoid passing raw any objects or massive optional classes.

Learning outcomes

  • Explain generic constraints and discriminated union patterns.
  • Apply conditional type inference to extract nested payload signatures.
  • Evaluate structural type safety against runtime validation boundaries.

Trade-offs

Advanced TypeScript types improve compile-time API safety and developer velocity, but over-complex conditional types can increase compiler build latency.

Evidence assessment

Theory and decision mastery

not-started · 0%
theory0%
decision0%
activityNot mapped
projectNot mapped
1. What defines TypeScript's structural type system?
2. How should untrusted external JSON data be handled in TypeScript?
3. What risk occurs when overusing complex nested conditional types in TypeScript?

Decision scenario

A team is designing a client-server API contract in TypeScript with diverse event types.

Which pattern ensures safe handling of multi-variant API payloads?

Primary sources