Generic Patterns

Shapes You'll See Everywhere

Generic Patterns

A consolidated tour of the most common generic patterns — containers, callbacks, fluent builders, mappers.

4 min read Level 2/5 #typescript#generics#patterns
What you'll learn
  • Recognize idiomatic generic shapes
  • Pick patterns by intent

A roundup of generic shapes you’ll see — and use — constantly.

Container

class Box<T> {
  constructor(public value: T) {}
}

The simplest: a class or type holds a value of T.

Mapper

function map<T, U>(arr: T[], fn: (item: T) => U): U[] { /* ... */ }

Transforms each element from T to U.

Wrapper That Adds Fields

function withId<T>(item: T): T & { id: string } {
  return { ...item, id: crypto.randomUUID() };
}

Returns the input’s type intersected with extra fields.

Result / Either

type Result<T, E = Error> =
  | { ok: true; data: T }
  | { ok: false; error: E };

Discriminated union over success and failure.

Fluent Builder

class Query<T extends Record<string, unknown> = {}> {
  private filters: Partial<T> = {};

  where<K extends string, V>(key: K, value: V): Query<T & Record<K, V>> {
    (this.filters as any)[key] = value;
    return this as any;
  }

  build(): T { return this.filters as T; }
}

const q = new Query()
  .where("status", "active")
  .where("limit", 10)
  .build();
// q: { status: string; limit: number }

Each where accumulates type info, ending with a fully typed result. (The implementation uses any casts; the type-level magic is in the signatures.)

Key-Value Helper

function get<T, K extends keyof T>(obj: T, key: K): T[K] {
  return obj[key];
}

Type-safe property access.

Generic Identity With Constraint

function freeze<T extends object>(x: T): Readonly<T> {
  return Object.freeze(x);
}

Same shape coming out, but read-only.

When To Stop Adding Generics

Generics serve type information. If you find yourself fighting the type system to add a sixth parameter, it’s usually a sign that the API needs to be split or simplified.

Up Next

The fanciest move — types that reference themselves.

Recursive Types →