TypeScript Generics That Will Break Your Brain
Master conditional types with infer, mapped type modifiers, and template literal types
1. Conditional Types with infer
Conditional types let you extract and manipulate type information during type evaluation.
typescript
// Extract return type
type ReturnType<T> = T extends (...args: any[]) => infer R ? R : never
// Extract tuple elements
type Head<T> = T extends readonly [infer H, ...any[]] ? H : never
type Tail<T> = T extends readonly [...any[], infer L] ? L : never
type First = Head<[string, number, boolean]> // string
type Last = Tail<[string, number, boolean]> // boolean2. Mapped Type Modifiers
Use + and - modifiers to add or remove readonly and ? modifiers.
typescript
// Remove optional and readonly modifiers
type Mutable<T> = { -readonly [P in keyof T]: T[P] }
type Required<T> = { [P in keyof T]-?: T[P] }
// Filter function properties
type FunctionKeys<T> = {
[K in keyof T]: T[K] extends Function ? K : never
}[keyof T]
type Functions<T> = Pick<T, FunctionKeys<T>>3. Template Literal Types
Build type-safe APIs with template literal types and parameter extraction.
typescript
// Extract route parameters
type ExtractParams<T> = T extends `${string}:${infer P}/${infer R}`
? { [K in P]: string } & ExtractParams<R>
: T extends `${string}:${infer P}`
? { [K in P]: string }
: {}
type Route = '/users/:id/posts/:postId'
type Params = ExtractParams<Route> // { id: string; postId: string }Putting It Together
Build a completely type-safe API client:
typescript
interface ApiSchema {
'GET /users': { users: User[] }
'GET /users/:id': { user: User }
'POST /users': { user: User }
}
type Method<T> = T extends `${infer M} ${string}` ? M : never
type Path<T> = T extends `${string} ${infer P}` ? P : never
class TypeSafeClient {
request<K extends keyof ApiSchema>(
endpoint: K,
params?: ExtractParams<Path<K>>
): Promise<ApiSchema[K]> {
// Implementation
}
}
// Usage - fully type-checked
const client = new TypeSafeClient()
client.request('GET /users/:id', { id: '123' })These patterns enable compile-time validation of complex business logic, making impossible states unrepresentable and APIs that never go out of sync.