Welcome back! I am Mihir, and in this lesson we will look at real-world generic examples in TypeScript.
Generics are not only theory. You will use them constantly in real apps.
Generic API Function
async function fetchJson<T>(url: string): Promise<T> {
const response = await fetch(url);
return response.json() as Promise<T>;
}Usage:
type User = {
id: number;
name: string;
};
const user = await fetchJson<User>("/api/user/1");Now TypeScript knows user has id and name.
Generic API Response
type ApiResponse<T> = {
success: boolean;
data: T;
error?: string;
};
type Product = {
id: number;
name: string;
price: number;
};
type ProductResponse = ApiResponse<Product>;This keeps response structure consistent across your app.
Generic Repository
interface Repository<T> {
findAll(): T[];
findById(id: number): T | undefined;
save(item: T): void;
}
class MemoryRepository<T extends { id: number }> implements Repository<T> {
private items: T[] = [];
findAll(): T[] {
return this.items;
}
findById(id: number): T | undefined {
return this.items.find((item) => item.id === id);
}
save(item: T): void {
this.items.push(item);
}
}The constraint ensures every item has an id.
Generic Form Field
type FormField<T> = {
value: T;
error?: string;
touched: boolean;
};
const emailField: FormField<string> = {
value: "mihir@example.com",
touched: false,
};
const ageField: FormField<number> = {
value: 28,
touched: true,
};Different fields can store different value types.
Generic Result Type
type Result<T> =
| { success: true; data: T }
| { success: false; error: string };Usage:
function getUser(): Result<User> {
return {
success: true,
data: {
id: 1,
name: "Mihir",
},
};
}This pattern works well for operations that can fail.
Generic Select Option
type SelectOption<T> = {
label: string;
value: T;
};
const roleOptions: SelectOption<"admin" | "user">[] = [
{ label: "Admin", value: "admin" },
{ label: "User", value: "user" },
];The option label is always a string, but the value can be flexible.
Quick Recap
- Generics are useful in APIs, repositories, forms, and UI models.
- Generic wrappers keep repeated structures clean.
- Constraints make generic helpers safer.
- Generic union types can model success and failure cleanly.
- Real projects use generics to keep flexibility without losing type safety.
Next up, we start utility types with Partial →.