Generics
Learn how to write reusable, type-safe functions, interfaces, and classes using generics.
Reading Time
20 min
Lesson
Lesson 19 of 30
The Problem Generics Solve
Without generics, a reusable function either loses type safety (typing a parameter as any) or has to be duplicated for every type it needs to support. Generics let a function stay both reusable and fully type-safe.
Without Generics: Losing Type Safety
function firstElement(arr: any[]): any {
return arr[0];
}
const num = firstElement([1, 2, 3]); // typed as 'any' — no safety at allWith Generics: Type Safety Preserved
function firstElement<T>(arr: T[]): T {
return arr[0];
}
const num = firstElement([1, 2, 3]); // inferred as number
const str = firstElement(["a", "b", "c"]); // inferred as stringHow Generic Type Parameters Work
<T> declares a placeholder type parameter. When the function is called, TypeScript infers T from the arguments passed in, and uses that specific type everywhere T appears in the signature.
Multiple Type Parameters
A function can accept more than one type parameter, each inferred independently from the arguments.
Multiple Type Parameters Example
function pair<A, B>(first: A, second: B): [A, B] {
return [first, second];
}
const result = pair("age", 25); // inferred as [string, number]Generic Interfaces
Interfaces can be generic too, letting you describe a reusable shape — like an API response wrapper — that works with any inner data type.
A Generic Interface
interface ApiResponse<T> {
data: T;
success: boolean;
}
const userResponse: ApiResponse<{ name: string }> = {
data: { name: "Alice" },
success: true,
};Generic Classes
Classes can be generic as well, useful for building reusable data structures like a typed stack, queue, or cache.
A Generic Class
class Box<T> {
constructor(private value: T) {}
getValue(): T {
return this.value;
}
}
const numberBox = new Box<number>(42);
const stringBox = new Box("hello"); // T inferred as stringT is Just a Convention
T, K, V, and U are naming conventions, not special syntax — you can name a type parameter anything, though single, capitalized letters are the common style for generic code.
Best Practice
Reach for generics as soon as you notice a function or class working identically across multiple types, but with any or type duplication as the only alternatives. Let TypeScript infer the type parameter from arguments whenever possible instead of specifying it explicitly.