@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
/**
* @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 });jsconfig.json for this example
{
"compilerOptions": {
"checkJs": true,
"noEmit": true,
"strict": true,
"target": "es2022",
"module": "nodenext",
"types": []
},
"include": ["*.js"]
} /**
* @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'.jsconfig.json for this example
{
"compilerOptions": {
"checkJs": true,
"noEmit": true,
"strict": true,
"target": "es2022",
"module": "nodenext",
"types": []
},
"include": ["*.js"]
} /**
* @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'.jsconfig.json for this example
{
"compilerOptions": {
"checkJs": true,
"noEmit": true,
"strict": true,
"target": "es2022",
"module": "nodenext",
"types": []
},
"include": ["*.js"]
} /** @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;
}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} tagstypestagsasstring[]. - A function whose parameters all come from a
@typeor@callbacksignature needs no@paramtags; mixing both on one function is confusing and best avoided. - Without a type in braces,
@param name descriptiondocuments 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
- JSDoc Reference: @param and @returns · TypeScript handbook
- @param · JSDoc
- Type Checking JavaScript Files: parameters are optional by default · TypeScript handbook
Last reviewed 20 October 2026.