TypeScript
Functions & Generics
Typing functions
// Parameters and return type
function multiply(a: number, b: number): number {
return a * b;
}
// Optional and default parameters
function greet(name: string, greeting: string = "Hello"): string {
return `${greeting}, ${name}`;
}
// Arrow function type
const divide: (a: number, b: number) => number = (a, b) => a / b;
Generics
Generics let you write reusable code that works with any type while keeping full type safety. The type is a parameter, written in angle brackets:
function identity<T>(value: T): T {
return value;
}
identity<string>("hello"); // T = string
identity(42); // T = number (inferred)
Without generics you'd either lose type info (using any) or write one function per type. With generics, the return type matches the input:
function first<T>(arr: T[]): T | undefined {
return arr[0];
}
const n = first([1, 2, 3]); // number | undefined
const s = first(["a", "b"]); // string | undefined
Constraining generics
Use extends to require that a type parameter has certain properties:
function longest<T extends { length: number }>(a: T, b: T): T {
return a.length >= b.length ? a : b;
}
longest("hello", "hi"); // ✅ strings have length
longest([1, 2, 3], [4]); // ✅ arrays have length
longest(10, 20); // ❌ numbers have no length
💡
Generics power type-safe collections, utility functions, React hooks (useState<T>), and API clients. They're one of TypeScript's most valuable features.
Generic interfaces
interface ApiResponse<T> {
data: T;
status: number;
error?: string;
}
const res: ApiResponse<User[]> = { data: users, status: 200 };
Watch & Learn
A recommended video to watch alongside this chapter.
More “Functions & Generics” videos on YouTube