Generics in TypeScript are a powerful feature that allows developers to create reusable components and functions that can work with a variety of data types while maintaining type safety. By using generics, you can define a placeholder for a type that can be specified later, making your code more flexible and adaptable to different scenarios.
Generics are particularly useful in scenarios where you want to create data structures or functions that can operate on multiple types without sacrificing the benefits of TypeScript's static type checking.
At its core, a generic type is defined using angle brackets (`
One of the simplest use cases for generics is in functions. Here’s an example of a generic function that returns the first element of an array:
function firstElement<T>(arr: T[]): T | undefined {
return arr[0];
}
const numberArray = [1, 2, 3];
const firstNumber = firstElement(numberArray); // returns 1
const stringArray = ['a', 'b', 'c'];
const firstString = firstElement(stringArray); // returns 'a'
Generics can also be used in interfaces to create flexible data structures. For example, you can define a generic interface for a response object:
interface ApiResponse<T> {
data: T;
error?: string;
}
const response: ApiResponse<{ id: number; name: string }> = {
data: { id: 1, name: 'John Doe' },
};
function merge<T extends object, U extends object>(obj1: T, obj2: U): T & U {
return { ...obj1, ...obj2 };
}
In conclusion, generics in TypeScript enable developers to create flexible and reusable code while ensuring type safety. By understanding how to implement and utilize generics effectively, you can enhance your TypeScript applications and improve maintainability.