TS Generics
Generics let a function, type, or class work with many types while keeping the relationship between input and output. TypeScript's superpower for building reusable code.
Basic generic function
TS
function first<T>(items: T[]): T | undefined {
return items[0];
}
const a = first(['x', 'y']); // string | undefined
const b = first([1, 2, 3]); // number | undefined
const c = first<boolean>([true, false]); // boolean | undefined — explicit
Multiple type parameters
TS
function pair<A, B>(a: A, b: B): [A, B] {
return [a, b];
}
const p = pair('hi', 42); // [string, number]
Constraints — extends
TS
function longest<T extends { length: number }>(a: T, b: T): T {
return a.length >= b.length ? a : b;
}
longest('hi', 'hello'); // string
longest([1,2], [3,4,5]); // number[]
// longest(1, 2); // ✗ number has no .length
Default type arguments
TS
function create<T = string>(value: T): T[] {
return [value];
}
create(42); // number[]
create<boolean>(true);
create(); // ✗ — T defaults to string but value is required
Generic types & interfaces
TS
type Result<T> = { ok: true; value: T } | { ok: false; error: string };
interface Repo<T> {
find(id: number): Promise<T | null>;
save(value: T): Promise<void>;
}
Generic classes
TS
class Stack<T> {
private items: T[] = [];
push(item: T) { this.items.push(item); }
pop(): T | undefined { return this.items.pop(); }
peek(): T | undefined { return this.items[this.items.length - 1]; }
}
const s = new Stack<number>();
s.push(1); s.push(2);
const n = s.pop(); // number | undefined
Tip: Write generics when you have a relationship between types — input/output, container/contents, parameter/return. Don't add generics "just in case" — they make signatures harder to read.
Example
Example
function first<T>(items: T[]): T | undefined {
return items[0];
}
console.log(first<string>(['a', 'b']));
console.log(first([1, 2, 3])); // T inferred as number
// Generic with constraint
function longest<T extends { length: number }>(a: T, b: T): T {
return a.length >= b.length ? a : b;
}
console.log(longest('hello', 'hi'));
Try it Yourself »
Exercise
Constraint syntax — keyword between T and the bound.
function key<T
object>(o: T) {}
Seven letters.
Discussion
Loading…