JSDoc tag

@param

  • Checked by TypeScript
  • Tested with TypeScript 5.9
  • Alias @arg
  • Alias @argument

@param {Type} name gives the parameter name the type Type, and TypeScript checks both sides: inside the function, name has that type, and every call must pass something assignable to it. It is the JavaScript spelling of name: Type in a TypeScript parameter list. @arg and @argument are aliases.

Untyped parameters in a checked file are implicitly any, which strict reports as TS7006. A @param for each parameter is the usual fix, and it is the tag you will write most often.

At a glance

Use JSDoc in a .js file TypeScript in a .ts file
A parameter /** @param {string} sku */ function f(sku: string) {}
Optional /** @param {string} [label] */ function f(label?: string) {}
With a default /** @param {number} [digits=2] */ function f(digits = 2) {} function f(digits: number = 2) {}
Rest parameters /** @param {...string} tags */ function f(...tags) {} function f(...tags: string[]) {}
An options object /** * @param {object} [options] * @param {string} [options.currency] */ function f(options?: { currency?: string }) {}

Examples

cart.js cart.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
/**
 * @param {string} sku
 * @param {number} quantity
 * @param {{ giftWrap?: boolean }} [options]
 * @returns {string}
 */
export function describeLine(sku, quantity, options) {
  const wrap = options?.giftWrap ? " (gift wrapped)" : "";
  return `${quantity} × ${sku}${wrap}`;
}

describeLine("TEE-01", 2);
describeLine("MUG-07", 1, { giftWrap: true });
export function describeLine(sku: string, quantity: number, options?: { giftWrap?: boolean }): string {
  const wrap = options?.giftWrap ? " (gift wrapped)" : "";
  return `${quantity} × ${sku}${wrap}`;
}

describeLine("TEE-01", 2);
describeLine("MUG-07", 1, { giftWrap: true });
Typing parameters with @param.
jsconfig.json for this example
{
  "compilerOptions": {
    "checkJs": true,
    "noEmit": true,
    "strict": true,
    "target": "es2022",
    "module": "nodenext",
    "types": []
  },
  "include": ["*.js"]
}
cart.js Error confirmed 5.9.3 TypeScript 5.9.3, run 21 October 2026: cart.js(11,19): error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'. 6.0.3 TypeScript 6.0.3, run 21 October 2026: the same as 5.9.3. cart.js(11,19): error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'. 7.0.2 TypeScript 7.0.2, run 21 October 2026: the same as 5.9.3. cart.js(11,19): error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'. checked 21 October 2026
/**
 * @param {string} sku
 * @param {number} quantity
 */
export function addLine(sku, quantity) {
  return { sku, quantity };
}

const fromForm = "2";
addLine("TEE-01", fromForm);error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'.
An argument of the wrong type, caught at the call.
jsconfig.json for this example
{
  "compilerOptions": {
    "checkJs": true,
    "noEmit": true,
    "strict": true,
    "target": "es2022",
    "module": "nodenext",
    "types": []
  },
  "include": ["*.js"]
}
price.js price.ts Error confirmed 5.9.3 TypeScript 5.9.3, run 21 October 2026: price.js(19,21): error TS2322: Type 'string' is not assignable to type 'number'. price.ts(12,21): error TS2322: Type 'string' is not assignable to type 'number'. 6.0.3 TypeScript 6.0.3, run 21 October 2026: the same as 5.9.3. price.js(19,21): error TS2322: Type 'string' is not assignable to type 'number'. price.ts(12,21): error TS2322: Type 'string' is not assignable to type 'number'. 7.0.2 TypeScript 7.0.2, run 21 October 2026: the same as 5.9.3. price.js(19,21): error TS2322: Type 'string' is not assignable to type 'number'. price.ts(12,21): error TS2322: Type 'string' is not assignable to type 'number'. checked 21 October 2026
/**
 * @param {number} amount
 * @param {object} [options]
 * @param {string} [options.currency="USD"] ISO 4217 code
 * @param {number} [options.digits=2] digits after the decimal point
 * @returns {string}
 */
export function formatPrice(amount, { currency = "USD", digits = 2 } = {}) {
  return new Intl.NumberFormat("en-US", {
    style: "currency",
    currency,
    maximumFractionDigits: digits,
  }).format(amount);
}

formatPrice(19.5);
formatPrice(19.5, { currency: "EUR" });
formatPrice(19.5, { digits: "2" });error TS2322: Type 'string' is not assignable to type 'number'.
export function formatPrice(amount: number, { currency = "USD", digits = 2 }: { currency?: string; digits?: number } = {}): string {
  return new Intl.NumberFormat("en-US", {
    style: "currency",
    currency,
    maximumFractionDigits: digits,
  }).format(amount);
}

formatPrice(19.5);
formatPrice(19.5, { currency: "EUR" });
formatPrice(19.5, { digits: "2" });error TS2322: Type 'string' is not assignable to type 'number'.
Documenting the properties of an options object, checked at every call.
jsconfig.json for this example
{
  "compilerOptions": {
    "checkJs": true,
    "noEmit": true,
    "strict": true,
    "target": "es2022",
    "module": "nodenext",
    "types": []
  },
  "include": ["*.js"]
}
cart.js Error confirmed 5.9.3 TypeScript 5.9.3, run 21 October 2026: cart.js(2,21): error TS8024: JSDoc '@param' tag has name 'qty', but there is no parameter with that name. cart.js(4,24): error TS7006: Parameter 'quantity' implicitly has an 'any' type. 6.0.3 TypeScript 6.0.3, run 21 October 2026: the same as 5.9.3. cart.js(2,21): error TS8024: JSDoc '@param' tag has name 'qty', but there is no parameter with that name. cart.js(4,24): error TS7006: Parameter 'quantity' implicitly has an 'any' type. 7.0.2 TypeScript 7.0.2, run 21 October 2026: the same as 5.9.3. cart.js(2,21): error TS8024: JSDoc '@param' tag has name 'qty', but there is no parameter with that name. cart.js(4,24): error TS7006: Parameter 'quantity' implicitly has an 'any' type. checked 21 October 2026
/** @param {number} qty */error TS8024: JSDoc '@param' tag has name 'qty', but there is no parameter with that name.
export function double(quantity) {error TS7006: Parameter 'quantity' implicitly has an 'any' type.
  return quantity * 2;
}
A @param name that matches no parameter.
jsconfig.json for this example
{
  "compilerOptions": {
    "checkJs": true,
    "noEmit": true,
    "strict": true,
    "target": "es2022",
    "module": "nodenext",
    "types": []
  },
  "include": ["*.js"]
}

Optional parameters and defaults

Square brackets around the name make the parameter optional: @param {string} [label]. Inside the function its type is string | undefined, and callers may leave it out. The older Closure form, @param {string=} label, means the same thing.

A default goes inside the brackets, @param {number} [digits=2], for readers and editors. The default that applies is the one in the code, function f(digits = 2), and it is also what removes undefined from the type inside the function.

Options objects and destructuring

Describe an object parameter's properties with dotted names: @param {object} [options] followed by @param {string} [options.currency]. TypeScript builds the object type from those lines, as the third example shows; a wrong property type in a call is TS2322.

This also works when the function destructures the object, function formatPrice(amount, { currency, digits } = {}). The parameter has no name of its own, so the tags are matched by position, and the name you write in them (options here) is for readers.

Names must match

TypeScript matches each @param to a parameter by name. A tag whose name matches nothing is TS8024, and the parameter it was meant for stays untyped, so strict adds TS7006, as the last example shows. Renaming a parameter with the editor's rename command updates the tag as well.

Gotchas

  • Rest parameters use the element type with three dots: @param {...string} tags types tags as string[].
  • A function whose parameters all come from a @type or @callback signature needs no @param tags; mixing both on one function is confusing and best avoided.
  • Without a type in braces, @param name description documents the parameter but leaves it untyped.

Questions

How do I mark a parameter as optional in JSDoc?

Put its name in square brackets: @param {string} [label]. Add a default after an equals sign, [label="Item"], if the function has one.

What is the difference between @param, @arg and @argument?

None. TypeScript reads all three the same way; @param is the common one.

Sources

Last reviewed 20 October 2026.