What Are Generics?
Generics allow you to write reusable components that work with a variety of types rather than a single one. Think of them as type-level functions.
Basic Generic Functions
function identity<T>(arg: T): T {
return arg
}
The type variable T captures whatever type the user provides, making it available later in the function signature.
Generic Constraints
Sometimes you want to constrain what types can be passed. Use the extends keyword:
function getLength<T extends { length: number }>(arg: T): number {
return arg.length
}
Real-World Patterns
Generics shine in API response wrappers, repository patterns, and utility types. Here's a typed API response wrapper:
interface ApiResponse<T> {
success: boolean
data: T
message?: string
}
Conditional Types
TypeScript's conditional types let you implement type-level logic: T extends U ? X : Y. Combined with infer, they unlock powerful meta-programming patterns used throughout popular libraries.
Mapped Types
Mapped types transform existing types into new ones. Partial<T>, Required<T>, and Readonly<T> are all implemented as mapped types in the TypeScript standard library.