Frontend5 min read
TypeScript Generics: The Patterns I Actually Use, Not the Ones in Tutorials
Most generics tutorials build a contrived stack or queue class. Here's where generics actually earn their keep in real application code.
Tanjil Ahmed
Lead Software Engineer · Notionhive
Generics tutorials love a `Stack<T>` example that's technically correct and never resembles anything in a real codebase. In practice, the generics that pull their weight in application code show up in a much narrower, more useful set of places.
- API response wrappers — `ApiResponse<T>` typed once, reused across every endpoint, catching shape mismatches at compile time.
- Reusable data-fetching hooks (`useQuery<TData>`) so a single hook serves every resource type with full inference.
- Constrained generics (`<T extends { id: string }>`) when a function needs to guarantee a shape without knowing the full type.
- Utility types built from `keyof` and mapped types for form state, so field names stay in sync with a model automatically.
The generics that earn their complexity are the ones solving a real duplication problem — the same logic written once instead of five times with five slightly different types. If a generic isn't removing duplication, it's usually adding ceremony instead of value.
A generic that doesn't remove real duplication is decoration. The useful ones are boring, and they show up in every API layer.
