Generics
Write reusable code that works with any type while staying type-safe.
Syntax
function identity<T>(value: T): T { return value; }Generics let you write functions and types that work with many types without losing type safety. A type parameter, usually written <T>, acts as a placeholder for a type chosen when the code is used.
Why generics?
Without them you would either duplicate code for each type or fall back to any and lose safety. Generics give you both reuse and safety.
Example
Loading editorβ¦
Press Run to execute the code.
When to use it
- A reusable Stack data structure is written once with a type parameter so it works for both number[] and string[] stacks.
- A caching utility function is generic so it stores and retrieves any value type while preserving type information.
- A library's wrapValue function is generic so it wraps any input into an object without losing the input's type.
More examples
Generic identity function
The simplest generic: a function that returns its input with the same type, letting TypeScript infer T from the argument.
function identity<T>(value: T): T {
return value;
}
const num = identity(42); // T inferred as number
const str = identity('hello'); // T inferred as stringGeneric wrapper type
A generic function that wraps any single value into an array, with the element type inferred from the argument.
function wrapInArray<T>(value: T): T[] {
return [value];
}
const nums = wrapInArray(1); // number[]
const strs = wrapInArray('hello'); // string[]Generic Stack class
A generic Stack class parameterised on T so it can hold any type while enforcing consistent push and pop types.
class Stack<T> {
private items: T[] = [];
push(item: T): void { this.items.push(item); }
pop(): T | undefined { return this.items.pop(); }
peek(): T | undefined { return this.items[this.items.length - 1]; }
}
const stack = new Stack<number>();
stack.push(1);
stack.push(2);
console.log(stack.peek()); // 2
Discussion