The Magic of Generics
Lesson Overview
Learn how to write reusable, type-safe components using TypeScript Generics.
The Magic of Generics
Generics are one of the most powerful features of TypeScript. They allow you to create components (functions, classes, or interfaces) that work with a variety of types while still maintaining full type safety.
The Problem
Imagine you want to create a function that returns the first element of an array.
function getFirstElement(arr: any[]): any {
return arr[0];
}
const numbers = [1, 2, 3];
const firstNum = getFirstElement(numbers); // TypeScript thinks firstNum is 'any'
By using any, we lose all type information. We want a way to say: “This function takes an array of some type, and it returns an element of that same type.”
The Solution: Generics
We can use a type variable (usually denoted as <T>) to capture the type provided by the user.
function getFirstElement<T>(arr: T[]): T {
return arr[0];
}
const numbers = [1, 2, 3];
const firstNum = getFirstElement(numbers); // TypeScript correctly infers firstNum is 'number'
const names = ["Alice", "Bob"];
const firstName = getFirstElement(names); // TypeScript correctly infers firstName is 'string'
Generic Interfaces
You can also use generics with interfaces to create flexible data structures.
interface ApiResponse<T> {
data: T;
status: number;
message: string;
}
interface User {
id: number;
name: string;
}
const userResponse: ApiResponse<User> = {
data: { id: 1, name: "Alice" },
status: 200,
message: "Success"
};
Generic Constraints
Sometimes you want to limit what types can be passed to a generic. You can use the extends keyword to add a constraint.
interface HasLength {
length: number;
}
function logLength<T extends HasLength>(item: T): void {
console.log(item.length);
}
logLength("Hello"); // OK: String has length
logLength([1, 2, 3]); // OK: Array has length
logLength(123); // Error: Number does not have a 'length' property.
Summary
Generics allow you to:
- Avoid code duplication: One function can work for many types.
- Maintain Type Safety: Unlike
any, generics preserve the actual type of your data. - Build Flexible APIs: Perfect for utility functions, API responses, and reusable components.