TS TypeScript3 / 4
Generics
📌 WHAT
Generics allow writing functions, classes, and interfaces that work with ANY type while still being type-safe. The type becomes a parameter.
💡 WHY
Without generics, you'd either write the same code 10 times for 10 types, or use 'any' and lose all type safety. Generics give you flexibility AND safety.
⏰ WHEN / WHERE
Writing utility functions, API wrappers, data structures, reusable hooks, or any code that should work for multiple types.
🔧 HOW
Use <T> syntax. T (or any letter) is a type variable. TypeScript infers the type when you call the function, or you can specify it explicitly.
Code Examples
#1Generics in functions and interfaces
Generics in functions and interfaces
typescript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
// WITHOUT generics — must write for each typefunction getFirstNumber(arr: number[]): number { return arr[0]; }function getFirstString(arr: string[]): string { return arr[0]; }// WITH generics — write once, works for any typefunction getFirst<T>(arr: T[]): T {return arr[0];}// TypeScript infers the type automaticallygetFirst([1, 2, 3]); // TypeScript knows: returns numbergetFirst(["a", "b", "c"]); // TypeScript knows: returns stringgetFirst([{ id: 1 }]); // TypeScript knows: returns { id: number }// Or specify explicitlygetFirst<string>(["a", "b"]); // explicit type argument// Generic with constraint — T must have id propertyfunction findById<T extends { id: number }>(items: T[], id: number): T | undefined {return items.find(item => item.id === id);}// Works for any object that has an id!findById(users, 1); // ✅ User has idfindById(products, 5); // ✅ Product has id// Generic interface — super useful for API responses!interface ApiResponse<T> {data: T;status: number;message: string;timestamp: string;}// One interface, infinite usestype UsersResponse = ApiResponse<User[]>;type UserResponse = ApiResponse<User>;type ProductResponse = ApiResponse<Product>;// Generic React component (in TypeScript)interface ListProps<T> {items: T[];renderItem: (item: T) => React.ReactNode;keyExtractor: (item: T) => string;}function List<T>({ items, renderItem, keyExtractor }: ListProps<T>) {return (<ul>{items.map(item => (<li key={keyExtractor(item)}>{renderItem(item)}</li>))}</ul>);}
Practice This Concept
Open the playground, paste any example, and experiment. The best way to learn is by breaking things.
Open in Playground