Advanced Types
Generics
Write reusable, type-safe code with generics — TypeScript's most powerful feature.
What are Generics?
Generics let you write code that works with multiple types without sacrificing type safety. Think of them as type-level variables.
Generic Constraints
You can constrain what types a generic accepts using extends.
Generic Interfaces and Classes
Generics work with interfaces and classes too, making it possible to build reusable data structures.
Built-in Generic Types
TypeScript includes many built-in generic utility types like Array<T>, Promise<T>, Record<K, V>, and more.
Example
typescript
// Simple generic function
function identity<T>(value: T): T {
return value;
}
// Generic with constraint
function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
return obj[key];
}
const user = { id: 1, name: "Alice", email: "alice@example.com" };
const name = getProperty(user, "name"); // type: string
const id = getProperty(user, "id"); // type: number
// Generic interface
interface ApiResponse<T> {
data: T;
status: number;
message: string;
}
type UserResponse = ApiResponse<User>;
type ListResponse = ApiResponse<User[]>;
// 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];
}
get size(): number {
return this.items.length;
}
}
const numberStack = new Stack<number>();
numberStack.push(1);
numberStack.push(2);
console.log(numberStack.pop()); // 2
// Utility types
type Partial<T> = { [P in keyof T]?: T[P] };
type Readonly<T> = { readonly [P in keyof T]: T[P] };
type Pick<T, K extends keyof T> = { [P in K]: T[P] };
type UserPreview = Pick<User, 'id' | 'name'>;Try it yourself — TYPESCRIPT