Mastering TypeScript Generics: Real-World Patterns
Beyond the Basics
If you've ever written Array<T> or Promise<T>, you've used generics. But TypeScript's type system offers far more powerful patterns that can make your code dramatically safer and more expressive.
Pattern 1: Constrained Generics
Constrain your type parameters to ensure they have the properties you need:
function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
return obj[key]const user = { name: "Sarah", age: 28 } const name = getProperty(user, "name") // type: string const age = getProperty(user, "age") // type: number ```
Pattern 2: Generic React Components
Build type-safe, reusable UI components:
interface DataTableProps<T> {
data: T[]
columns: Column<T>[]
onRowClick?: (item: T) => voidexport function DataTable<T>({ data, columns, onRowClick }: DataTableProps<T>) { return ( <table> {data.map((item, i) => ( <tr key={i} onClick={() => onRowClick?.(item)}> {columns.map((col) => ( <td key={col.key}>{col.render(item)}</td> ))} </tr> ))} </table> ) } ```
Tip
Generic components preserve type information through the entire chain — from data to event handlers.
Pattern 3: Builder Pattern with Generics
Create fluent APIs that accumulate type information:
class QueryBuilder<T extends Record<string, unknown>> {
where<K extends keyof T>(key: K, value: T[K]): this {
// implementation
return this
}
}Pattern 4: Mapped Types
Transform types systematically:
type ReadOnly<T> = { readonly [K in keyof T]: T[K] }
type Optional<T> = { [K in keyof T]?: T[K] }
type Nullable<T> = { [K in keyof T]: T[K] | null }These patterns compose beautifully and form the foundation of most TypeScript utility libraries.
editor
Full-stack developer and open-source contributor. Writes about Node.js, databases, and system design. Core maintainer of several popular npm packages.
Comments (1)
The builder pattern example is so elegant! I've been using generics for years but never thought to apply them to fluent APIs like that.
Related Posts
Building a Design System with Tailwind CSS v4 and React
Learn how to create a scalable, token-based design system using Tailwind CSS v4's new CSS-first configuration and React component patterns.
The Complete Guide to Next.js 16 App Router
Everything you need to know about Next.js 16's App Router — from layouts and loading states to parallel routes and intercepting routes.
Optimizing React Performance: From 3s to 300ms
Real performance wins from a production React app — covering code splitting, memo strategies, virtualization, and the new React compiler.