Generics are one of TypeScript's most powerful features. They let you write flexible, reusable code while maintaining full type safety. Think of them as type-level functions.
Basic Generics
At their simplest, generics let you parameterize types. Instead of writing separate functions for arrays of strings, numbers, and objects, you write one function that works with any type and preserves that type information through the call.
Generic Constraints
Constraints let you narrow what types a generic accepts. Using extends, you can require that a type has certain properties. This is invaluable for building type-safe API wrappers and utility functions.