TypeScript Advanced Patterns: Generics and Utility Types

Oct 26, 2025
typescripttypespatternsgenerics
0

TypeScript enables expressive, safe APIs. This guide collects practical type patterns for large codebases.

Discriminated unions

type Shape = { kind: 'circle'; r: number } | { kind: 'rect'; w: number; h: number }
function area(s: Shape) { return s.kind === 'circle' ? Math.PI*s.r*s.r : s.w*s.h }

Type predicates

function isErr<T>(x: T | Error): x is Error { return x instanceof Error }

Mapped/conditional types

type ReadonlyDeep<T> = { readonly [K in keyof T]: ReadonlyDeep<T[K]> }

Branded types

type Brand<T, B extends string> = T & { __brand: B }
type UserId = Brand<string, 'UserId'>

API design

  • Prefer exact object types; avoid any; narrow with satisfies; return Result types

FAQ

Q: Are branded types runtime-safe?
A: Brands are compile-time only; pair with runtime validation (zod/io-ts) for inputs.

Related posts