TypeScript Generics Explained
Ad
What are Generics?
Generics let you write reusable code that works with any type while still keeping full type safety. Think of them as "type variables."
The Problem Generics Solve
// Without generics — you lose the type
function firstAny(arr: any[]): any { return arr[0]; }
const x = firstAny([1, 2, 3]); // x is "any" — no safety
// With generics — type is preserved
function first<T>(arr: T[]): T { return arr[0]; }
const n = first([1, 2, 3]); // n is number ✅
const s = first(["a", "b"]); // s is string ✅
Generic Interfaces
interface ApiResponse<T> {
data: T;
status: number;
}
const userRes: ApiResponse<User> = { data: user, status: 200 };
const listRes: ApiResponse<User[]> = { data: users, status: 200 };
Constraints with extends
// T must have a .length property
function logLength<T extends { length: number }>(item: T): T {
console.log(item.length);
return item;
}
logLength("hello"); // ✅ strings have length
logLength([1, 2, 3]); // ✅ arrays have length
logLength(123); // ❌ numbers don't
Real-World Example: A Typed Fetch
async function getJSON<T>(url: string): Promise<T> {
const res = await fetch(url);
return res.json();
}
const user = await getJSON<User>("/api/user"); // user is fully typed
FAQs
Why is it always called T?
Convention only (T = Type). You can name it anything: <TData>, <Item>. Use descriptive names for clarity.
Are generics a runtime cost?
No — they exist only at compile time and are erased in the output JS. Learn more in our TypeScript guides.
