DG
DevGuide
Run Code
Home/TypeScript/Generics
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 type
function getFirstNumber(arr: number[]): number { return arr[0]; }
function getFirstString(arr: string[]): string { return arr[0]; }
// WITH generics — write once, works for any type
function getFirst<T>(arr: T[]): T {
return arr[0];
}
// TypeScript infers the type automatically
getFirst([1, 2, 3]); // TypeScript knows: returns number
getFirst(["a", "b", "c"]); // TypeScript knows: returns string
getFirst([{ id: 1 }]); // TypeScript knows: returns { id: number }
// Or specify explicitly
getFirst<string>(["a", "b"]); // explicit type argument
// Generic with constraint — T must have id property
function 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 id
findById(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 uses
type 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