`function name<T>(...)` — Write Once, Use With Any Type
Generic Functions
Add `<T>` to a function and use `T` as a type in its signature. Callers can supply T explicitly or let inference figure it out.
What you'll learn
- Author a generic function
- Use generics with arrow functions
- Recognize the explicit vs inferred forms
A generic function declares one or more type parameters in <...>,
then uses them in the signature.
The Syntax
function identity<T>(value: T): T {
return value;
}
identity("hi"); // T = string, returns string
identity(42); // T = number, returns number
identity({ x: 1 }); // T = { x: number } <T> declares the parameter; T is used as a normal type in the
signature and body.
With Multiple Type Parameters
function pair<A, B>(a: A, b: B): [A, B] {
return [a, b];
}
const p = pair("Ada", 36); // [string, number] Arrow Function Form
const identity = <T>(value: T): T => value; In .tsx files, <T> collides with JSX — TS forces you to add a
hint:
const identity = <T,>(value: T): T => value; // trailing comma
// or
const identity = <T extends unknown>(value: T): T => value; Explicit Type Arguments
const x = identity<string>("hi");
const y = identity<number>(42); You CAN specify the type arguments. Usually unnecessary — TS infers them.
When to specify:
- Inference produces a wider type than you want
- The function has type parameters that don’t appear in the args
function make<T>(): T {
return {} as T;
}
const u = make<User>(); // ✓ explicit required (no args to infer from) A Common Generic Helper
function first<T>(arr: T[]): T | undefined {
return arr[0];
}
const a = first([1, 2, 3]); // number | undefined
const b = first(["x", "y"]); // string | undefined
const c = first([]); // undefined (T inferred as never) A more honest version of first — empty arrays return undefined.
Up Next
Generics with constraints — <T extends ...>.