error TS2554: Expected 2 arguments, but got 1. is reported when a call passes a number of arguments the function does not accept. TS2555 (Expected at least 1 arguments, but got 0.) is the same error for a function with a rest parameter.
JavaScript has a twist here. A parameter without a JSDoc type is treated as optional, so calling with fewer arguments is fine; once a function has @param tags its parameters are required unless a tag marks them optional. Too many arguments is reported either way.
At a glance
| Code | TS2554 |
|---|---|
| Message | Expected {0} arguments, but got {1}. |
Also on this page: TS2555 | Expected at least {0} arguments, but got {1}. |
| TypeScript's category | error |
| Listed under | Types do not match |
| Turned on by | No option: every checked file reports it |
| In .js files | Reported when the file is checked: checkJs in jsconfig.json, or // @ts-check at the top of the file |
The messages are TypeScript's own text from its diagnostic messages file (Apache-2.0); {0} and {1} are filled in by tsc for each error.
What it looks like
/**
* @param {number} cents
* @param {string} currency
*/
export function formatPrice(cents, currency) {
return new Intl.NumberFormat("en-US", { style: "currency", currency }).format(cents / 100);
}
formatPrice(1999);error TS2554: Expected 2 arguments, but got 1.
formatPrice(1999, "USD", "en-US");error TS2554: Expected 2 arguments, but got 3.
/**
* @param {string} level
* @param {...string} parts
*/
export function log(level, ...parts) {
console.log(`[${level}]`, ...parts);
}
log();error TS2555: Expected at least 1 arguments, but got 0.jsconfig.json for this example
{
"compilerOptions": {
"checkJs": true,
"noEmit": true,
"strict": true,
"target": "es2022",
"module": "nodenext",
"types": []
},
"include": ["*.js"]
} What causes it
- An argument was forgotten, or one is passed that the function does not take.
- The function's
@paramtags make every parameter required, but some are optional in practice.
How to fix it
Mark optional parameters in JSDoc
Write the name in brackets, @param {string} [currency], and give it a default in the code if it needs one (currency = "USD"). The tag can carry the default too, [currency="USD"], but the checker reads only the brackets; the code's default is what runs.
/**
* @param {number} cents
* @param {string} [currency] Defaults to US dollars.
*/
export function formatPrice(cents, currency = "USD") {
return new Intl.NumberFormat("en-US", { style: "currency", currency }).format(cents / 100);
}
formatPrice(1999);
formatPrice(1999, "EUR");
/**
* @param {string} level
* @param {...string} parts
*/
export function log(level, ...parts) {
console.log(`[${level}]`, ...parts);
}
log("info");
log("info", "cart saved", "3 items");jsconfig.json for this example
{
"compilerOptions": {
"checkJs": true,
"noEmit": true,
"strict": true,
"target": "es2022",
"module": "nodenext",
"types": []
},
"include": ["*.js"]
} Or change the call
When the function is right, pass what it expects. For a rest parameter (@param {...string} parts), the parameters before it are still required.
Gotchas
- A function that reads
argumentsinstead of named parameters accepts any number of arguments; the checker infers that from the body. - Spreading an array into a function with fixed parameters is a different error, TS2556.
Sources
- Type Checking JavaScript Files: Function parameters are optional by default · TypeScript handbook
- JSDoc Reference: @param and @returns · TypeScript handbook
- diagnosticMessages.json (TypeScript 5.9.3) · TypeScript on GitHub
Last reviewed 20 October 2026.