TypeScript3 min read
TypeScript Generics for Beginners
Write flexible, type-safe code that works with any type
S
Shahar Amir
TypeScript Generics for Beginners
Generics look scary but they're just placeholders for types. Let's demystify them.
The Problem
You want a function that works with any type:
typescript
123456
// Without generics - loses type infofunction first(arr: any[]): any { return arr[0];}
const num = first([1, 2, 3]); // type: any 😕The Solution: Generics
typescript
123456
function first<T>(arr: T[]): T { return arr[0];}
const num = first([1, 2, 3]); // type: number ✅const str = first(["a", "b"]); // type: string ✅T is a placeholder. TypeScript figures out what it is from usage.
Basic Syntax
typescript
123456789101112131415
// Functionfunction identity<T>(value: T): T { return value;}
// Arrow functionconst identity = <T>(value: T): T => value;
// Interfaceinterface Box<T> { value: T;}
// Type aliastype Container<T> = { item: T };Multiple Type Parameters
typescript
123456
function pair<A, B>(first: A, second: B): [A, B] { return [first, second];}
const result = pair("hello", 42);// type: [string, number]Constraining Types
Limit what T can be:
typescript
12345678
// T must have a length propertyfunction logLength<T extends { length: number }>(item: T): void { console.log(item.length);}
logLength("hello"); // ✅logLength([1, 2, 3]); // ✅logLength(123); // ❌ Error: number has no lengthReal-World Examples
API Response Wrapper
typescript
12345678
interface ApiResponse<T> { data: T; status: number; message: string;}
type UserResponse = ApiResponse<User>;type PostsResponse = ApiResponse<Post[]>;useState-like Hook
typescript
12345678910
function useLocalStorage<T>(key: string, initial: T) { const [value, setValue] = useState<T>(() => { const stored = localStorage.getItem(key); return stored ? JSON.parse(stored) : initial; }); return [value, setValue] as const;}
const [user, setUser] = useLocalStorage<User>("user", defaultUser);Object Key Access
typescript
1234567
function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] { return obj[key];}
const user = { name: "John", age: 30 };const name = getProperty(user, "name"); // type: stringconst age = getProperty(user, "age"); // type: numberDefault Types
typescript
123456
interface Container<T = string> { value: T;}
const a: Container = { value: "hello" }; // T is stringconst b: Container<number> = { value: 42 }; // T is numberMental Model
Think of generics like function parameters, but for types:
typescript
12345
// Regular function: value parametersfunction add(a: number, b: number) { ... }
// Generic function: type parametersfunction wrap<T>(value: T) { ... }When you call the function, you pass values. When you use the generic, you pass types (or let TypeScript infer them).
That's it. Generics = type placeholders. Start simple, and you'll get comfortable fast.
#generics#types#fundamentals
Stay Updated 📬
Get the latest tips and tutorials delivered to your inbox. No spam, unsubscribe anytime.