Type expression

Default type arguments

  • Generics
  • Since TypeScript 4.5

Brackets with an equals sign give a type parameter a default: @template [T=string]. When a type is used without type arguments, Field instead of Field<number>, or a class is created with nothing to infer from, the default is used. TypeScript 4.5 added defaults to JSDoc.

Defaults are most useful on generic @typedefs and classes, where they keep the common case short.

At a glance

Use JSDoc in a .js file TypeScript in a .ts file
A default /** @template [T=string] */ <T = string>
Constraint and default /** @template {string | number} [T=number] */ <T extends string | number = number>

Examples

field.js field.ts TypeScript 5.9.3 TypeScript 5.9.3, run 21 October 2026: No errors. 6.0.3 TypeScript 6.0.3, run 21 October 2026: the same as 5.9.3. No errors. 7.0.2 TypeScript 7.0.2, run 21 October 2026: the same as 5.9.3. No errors. checked 21 October 2026
/**
 * @template [T=string]
 * @typedef {{ value: T, error?: string }} Field
 */

/** @type {Field} */
const name = { value: "Jane" };

/** @type {Field<number>} */
const age = { value: 34 };

name.value.toUpperCase();
age.value.toFixed(0);

export { name, age };
type Field<T = string> = { value: T; error?: string };

const name: Field = { value: "Jane" };

const age: Field<number> = { value: 34 };

name.value.toUpperCase();
age.value.toFixed(0);

export { name, age };
A default type argument on a @typedef.
jsconfig.json for this example
{
  "compilerOptions": {
    "checkJs": true,
    "noEmit": true,
    "strict": true,
    "target": "es2022",
    "module": "nodenext",
    "types": []
  },
  "include": ["*.js"]
}
store.js Error confirmed 5.9.3 TypeScript 5.9.3, run 21 October 2026: store.js(15,11): error TS2345: Argument of type 'number' is not assignable to parameter of type 'string'. 6.0.3 TypeScript 6.0.3, run 21 October 2026: the same as 5.9.3. store.js(15,11): error TS2345: Argument of type 'number' is not assignable to parameter of type 'string'. 7.0.2 TypeScript 7.0.2, run 21 October 2026: the same as 5.9.3. store.js(15,11): error TS2345: Argument of type 'number' is not assignable to parameter of type 'string'. checked 21 October 2026
/** @template [T=string] */
export class Store {
  /** @type {T[]} */
  items = [];

  /** @param {T} item */
  add(item) {
    this.items.push(item);
  }
}

const notes = new Store();
notes.add("Restock mugs");
notes.add(42);error TS2345: Argument of type 'number' is not assignable to parameter of type 'string'.
A default applies when nothing else sets the type.
jsconfig.json for this example
{
  "compilerOptions": {
    "checkJs": true,
    "noEmit": true,
    "strict": true,
    "target": "es2022",
    "module": "nodenext",
    "types": []
  },
  "include": ["*.js"]
}
pair.js Error confirmed 5.9.3 TypeScript 5.9.3, run 21 October 2026: pair.js(2,27): error TS2706: Required type parameters may not follow optional type parameters. 6.0.3 TypeScript 6.0.3, run 21 October 2026: the same as 5.9.3. pair.js(2,27): error TS2706: Required type parameters may not follow optional type parameters. 7.0.2 TypeScript 7.0.2, run 21 October 2026: the same as 5.9.3. pair.js(2,27): error TS2706: Required type parameters may not follow optional type parameters. checked 21 October 2026
/** @template [K=string], V @typedef {{ key: K, value: V }} Pair */error TS2706: Required type parameters may not follow optional type parameters.

/** @type {Pair<string, number>} */
const pair = { key: "TEE-01", value: 12 };

export { pair };
A required type parameter cannot follow one with a default.
jsconfig.json for this example
{
  "compilerOptions": {
    "checkJs": true,
    "noEmit": true,
    "strict": true,
    "target": "es2022",
    "module": "nodenext",
    "types": []
  },
  "include": ["*.js"]
}

On classes

new Store() in the second example has no argument that mentions T, so the default applies and notes is a Store<string>; adding a number is TS2345. Without the default, T would be any in a .js file and nothing would be checked.

Defaults come last

Parameters with defaults must come after the ones without. @template [K=string], V is TS2706 ("Required type parameters may not follow optional type parameters"), as the third example shows.

Gotchas

  • Defaults do not affect inference when there is an argument to infer from: new Store([1, 2]) with a constructor parameter of type T[] would infer number.
  • Before TypeScript 4.5, a JSDoc type parameter could not have a default.

Questions

How do I give a JSDoc type parameter a default?

Put the name in brackets with the default after an equals sign: @template [T=unknown]. It works since TypeScript 4.5.

Sources

Last reviewed 20 October 2026.