Generics in TypeScript are a way to create reusable components that can work with multiple types while keeping the type safety and flexibility. They allow you to define functions, classes, and interfaces that can operate on a variety of types, making your code more flexible and reusable.
It took me a while to wrap my head around Generics but the way I think about it is that generics are placeholders for types. You can pass in a type as an argument and the generic will use that type instead of the original type.
function identity<T>(arg: T): T {
return arg;
}
Here we have a function that takes an argument of type T and returns an argument of type T. The T is a placeholder for the type. So it could be a string, a number, an array, an object, etc.
const result = identity<number>(123);
or
const result = identity<string>("hello");
In this post I wrote a while ago, I used generics to create a reusable Table component, allowing me to pass in any type of data without having to create a different table for each use case:
interface TableProps<T> {
headers: string[];
data: T[];
renderRow: (item: T) => React.ReactNode;
}
Here we have an interface that takes a generic type T. We can then use this interface to create a table component that can be used with any type of data.