← Live cheatsheet

TypeScript · cheatsheet

TypeScript cheatsheet

Utility types, narrowing tricks, the syntax that gets forgotten between projects.

https://yasirarfat.com/tutorials/cheatsheets/typescript — every section links back to the live page.

Utility types

Partial<T>every property optional
Required<T>every property non-optional
Readonly<T>all properties readonly
Pick<T, "a" | "b">subset of keys
Omit<T, "a">subtract keys
Record<K, V>object with K keys, V values
ReturnType<typeof fn>the return type of fn
Awaited<T>unwrap a Promise<T>
NonNullable<T>remove null | undefined

Narrowing patterns

Discriminated unions

type Result =
  | { ok: true; value: number }
  | { ok: false; error: string };

function handle(r: Result) {
  if (r.ok) return r.value;     // narrowed to success
  return r.error;                // narrowed to failure
}

Exhaustive switch via never

function area(s: Shape): number {
  switch (s.kind) {
    case 'square': return s.side ** 2;
    case 'circle': return Math.PI * s.radius ** 2;
    default: {
      const _: never = s;        // compile error if a case is missed
      return _;
    }
  }
}

Common gotchas

Index signatures (`{[k: string]: T}`) make ALL access return `T | undefined` when `noUncheckedIndexedAccess` is on. Treat that as a feature.

`as const` on object literals locks property types to their literal values — perfect for config tables.

Prefer `satisfies` over `as` when you want type-checking against a wider type but to keep the narrow inferred shape.