TypeScript: Patterns I Actually Use
Not a complete reference — just the parts I reach for. For everything else, ask AI.
The Stuff I Forget
Type extraction from objects
interface Building {
room: { door: string; walls: string[] };
}
type Walls = Building['room']['walls']; // string[]
keyof
type Point = { x: number; y: number };
type P = keyof Point; // "x" | "y"
Conditional types with inference
type GetReturnType<T> = T extends (...args: unknown[]) => infer R ? R : never;
type Num = GetReturnType<() => number>; // number
Template literal types
type SpaceChar = ' ' | '\n' | '\t';
type TrimLeft<S extends string> = S extends `${SpaceChar}${infer Rest}` ? TrimLeft<Rest> : S;
as const for literal types
const point = { x: 4, y: 2 } as const;
// { readonly x: 4, readonly y: 2 } — values are literal, not widened
Union narrowing shorthand
type Name = string | string[];
Patterns I Use Daily
Optional chaining in types
interface User {
name: string;
age?: number; // optional
readonly id: string; // immutable
}
Function type in interface
interface Handler {
onSubmit: (data: FormData) => void;
}
Generic constraint
function getFirst<T extends { id: string }>(items: T[]): T {
return items[0];
}
Intersection for extending without class
type WithTimestamps<T> = T & { createdAt: Date; updatedAt: Date };
type UserRow = WithTimestamps<User>;
My Rules
- Default to
typeunless I need declaration merging orextends(theninterface) - Avoid
any. Useunknown+ narrowing instead. ascasting is a smell — if I'm doing it a lot, something is wrong upstream- Prefer
readonlyon data that shouldn't mutate — catches bugs early