TypeScript Generics
Generics are one of the most powerful features in TypeScript. They allow us to write reusable, flexible components (like functions, classes, or interfaces) that can work with multiple data types, not just a single one. This greatly improves code reusability while maintaining type safety.
Why Do We Need Generics?
Imagine a simple function that takes a parameter and returns it directly.
Using the any type causes the function to lose type safety because the compiler doesn't know the specific type of the return value. Writing a function for each type is very tedious. Generics were created to solve this problem.
Creating Generic Functions
We can create a generic function identity that works for all types.
Here, <T> is a type variable, a special kind of variable used only to represent types, not values. It captures the type passed in by the user (like number), and then we can use this type inside the function.
Using Generic Functions
There are two ways to use generic functions:
-
Explicitly pass the type parameter:
-
Type inference: The compiler automatically determines the type of
Tbased on the passed argument.
Generic Constraints
Sometimes, we want a generic function to work with types that have specific properties. For example, a logging function might need to access the .length property of the parameter. In this case, we can use generic constraints.
We can create an interface to describe the constraint condition, then use the extends keyword to apply it.
Generic Interfaces
We can also create generic interfaces, allowing interface member types to be flexible.
Generic Classes
Classes can also be generic. Generic classes use <T> after the class name to define type parameters.
Generics are a very important part of TypeScript's type system. Mastering them allows you to write more general, robust, and reusable code.