Introduction to Generics
11 min read
Introduction to Generics
Generics let you write reusable code that works with any type while still maintaining type safety. Instead of using any, you parameterize the type — the caller decides what concrete type fills in the placeholder.
ts
// Without generics — loses type information
function firstAny(arr: any[]): any {
return arr[0];
}
// With generics — type is preserved
function first<T>(arr: T[]): T {
return arr[0];
}
const num = first([1, 2, 3]); // inferred: number
const str = first(["a", "b"]); // inferred: stringGeneric types can also be written as interfaces or type aliases, and generic parameters are inferred at the call site whenever possible.
ts
// Generic interface
interface ApiResponse<T> {
data: T;
status: number;
message: string;
}
// Generic class
class Stack<T> {
private items: T[] = [];
push(item: T): void {
this.items.push(item);
}
pop(): T | undefined {
return this.items.pop();
}
peek(): T | undefined {
return this.items[this.items.length - 1];
}
}Multiple type parameters
ts
function zip<A, B>(a: A[], b: B[]): [A, B][] {
return a.map((item, i) => [item, b[i]]);
}
const pairs = zip([1, 2, 3], ["a", "b", "c"]);
// [number, string][]Ready to test yourself?
Practice TypeScript— quiz & coding exercises