Generics are a crucial feature of TypeScript. They enable functions, classes, or interfaces to work with any type while preserving type safety. This allows you to define functions, interfaces, or classes without specifying the exact data type, thereby making the code more flexible and reusable.
For example, consider writing a function that accepts an array and returns its first element. Without generics, you might need to create multiple functions for different array types:
typescriptfunction getFirstNumber(arr: number[]): number { return arr[0]; } function getFirstString(arr: string[]): string { return arr[0]; }
Using generics, you can write a single function that works with any type:
typescriptfunction getFirstElement<T>(arr: T[]): T { return arr[0]; }
In the above example, <T> serves as a placeholder representing the data type provided later. When you call getFirstElement, TypeScript automatically infers the specific type of T based on the arguments passed:
typescriptlet numbers = [1, 2, 3]; let firstNumber = getFirstElement(numbers); // T is automatically inferred as the number type let strings = ["apple", "banana", "cherry"]; let firstString = getFirstElement(strings); // T is automatically inferred as the string type
This generative capability not only enhances code reusability but also maintains type safety, ensuring functions accept appropriate parameter types and return correct results. This is essential for building large, maintainable applications.