TypeScript Generic Defaults
A default type argument gives a type parameter a fallback type. The default applies when a call or annotation supplies no type and inference finds nothing to infer from.
A default fills in when inference has nothing
The createList function takes no value argument, so inference has nothing to read. The default makes the new list a string list.
function createList<T = string>(): T[] {
return [];
}
const labels = createList();
labels.push('pen');
labels.push('ruler');
console.log(labels);An explicit argument overrides the default
The same function with an explicit number argument builds a number list instead. Only that call changes.
function createList<T = string>(): T[] {
return [];
}
const counts = createList<number>();
counts.push(4);
counts.push(7);
console.log(counts);A default on a generic interface
The Box interface defaults its member type to string. A bare Box annotation uses the default, and an explicit argument replaces it.
interface Box<T = string> {
value: T;
}
const labelBox: Box = { value: 'pen' };
const countBox: Box<number> = { value: 4 };
console.log(labelBox.value);
console.log(countBox.value);Example
function firstOf<T = number>(first?: T): T[] {
const list: T[] = [];
if (first !== undefined) {
list.push(first);
}
return list;
}
interface Named<T = string> {
value: T;
label: string;
}
const counts = firstOf();
counts.push(3);
const entry: Named = { value: 'pen', label: 'item' };
console.log(counts);
console.log(entry.value);Key points
- A default sits after the parameter name with an equals sign, like a value default.
- Inference still wins when an argument gives the parameter a type.
- An explicit type argument overrides the default at that one call or annotation.
- Functions, interfaces and classes can all carry default type arguments.
- A default keeps simple call sites short while the full generic stays available.
In this example, firstOf is called with no argument, so its parameter falls back to the number default and the list accepts 3. The Named annotation also omits its type argument, so value is a string.
Try it Yourself
Edit the code, then press Run.
Running is simulated ยท TypeScript Playground
Exercise
When does a default type argument apply?