Generics let a function, interface, or class work over a variety of types while preserving the relationship between input and output types.
ts
function first<T>(arr: T[]): T | undefined {
return arr[0];
}
first([1, 2, 3]); // inferred T = number, returns number | undefined
first(["a", "b"]); // inferred T = string
interface Box<T> {
value: T;
}
const b: Box<string> = { value: "hi" };The type parameter `T` is a placeholder filled in at each call site, either explicitly (`first<number>([1,2,3])`) or inferred from the arguments. Generics avoid the loss of type information that `any` would introduce while still allowing one implementation to serve many types.