TypeScript Generic Functions in Depth
A generic function can declare several type parameters, one per independent type in the signature. The compiler infers each parameter from the arguments at the call.
Two parameters, inferred from both arguments
The pair function declares A and B as separate parameters. The call infers string for A and number for B at the same time.
function pair<A, B>(first: A, second: B): [A, B] {
return [first, second];
}
const entry = pair('pen', 4);
console.log(entry);
console.log(typeof entry[0]);
console.log(typeof entry[1]);Explicit type arguments at the call
Angle brackets after the function name state the parameters directly. The arguments must then match the stated types.
function pair<A, B>(first: A, second: B): [A, B] {
return [first, second];
}
const entry = pair<string, number>('pen', 4);
const label = pair<string, string>('pen', 'blue');
console.log(entry);
console.log(label);One parameter ties two positions together
The parameter T appears in both parameter positions, so both arguments share one type. The explicit number fixes T, and the string argument breaks the tie.
function sameType<T>(first: T, second: T): T[] {
return [first, second];
}
const sizes = sameType<number>(4, 'large');
console.log(sizes);Example
function zip<A, B>(left: A[], right: B[]): [A, B][] {
const pairs: [A, B][] = [];
const count = Math.min(left.length, right.length);
for (let i = 0; i < count; i++) {
pairs.push([left[i], right[i]]);
}
return pairs;
}
console.log(zip(['pen', 'ruler'], [4, 7]));Key points
- Multiple type parameters let two positions in one signature hold unrelated types.
- Inference reads every argument at once, so one call can fix several parameters.
- Explicit type arguments in angle brackets replace inference at a call site.
- One parameter used in two positions ties those positions to the same type.
- A mismatched second argument is refused when the tie fixes the parameter first.
In this example, zip infers A as string from the first array and B as number from the second array in one call. The result is an array of pairs that keep those two types side by side.
Try it Yourself
Edit the code, then press Run.
Running is simulated ยท TypeScript Playground
Exercise
What does pair<string, number>('pen', 4) do differently from pair('pen', 4)?