Skip to content
TypeScript Essentials

TypeScript Generics

Beginner Lesson 6 of 9

Generics allow you to create reusable components that work with multiple types.

// Without generics
function identity(arg: any): any {
return arg;
}
// With generics - preserves type
function identity<T>(arg: T): T {
return arg;
}
const num = identity<number>(42); // number
const str = identity<string>("hi"); // string
const inferred = identity(true); // boolean (inferred)
function first<T>(arr: T[]): T | undefined {
return arr[0];
}
const firstNum = first([1, 2, 3]); // number
const firstStr = first(["a", "b"]); // string
interface Container<T> {
value: T;
getValue(): T;
}
const numContainer: Container<number> = {
value: 42,
getValue() { return this.value; }
};
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];
}
}
const numStack = new Stack<number>();
numStack.push(1);
numStack.push(2);
interface HasLength {
length: number;
}
function logLength<T extends HasLength>(arg: T): T {
console.log(arg.length);
return arg;
}
logLength("hello"); // Works - string has length
logLength([1, 2, 3]); // Works - array has length
// logLength(123); // Error - number has no length
function pair<K, V>(key: K, value: V): [K, V] {
return [key, value];
}
const p1 = pair<string, number>("age", 25);
const p2 = pair("name", "Alice"); // Inferred
interface Response<T = any> {
data: T;
status: number;
}
const res1: Response = { data: "anything", status: 200 };
const res2: Response<User> = { data: user, status: 200 };

Continue to Modules →