TypeScript TS2554 — Expected N Arguments but Got M
Fix TS2554 by matching call arity to the signature, understanding optional and rest parameters, and avoiding trailing undefined arguments.
Symptoms
- error TS2554: Expected 2 arguments, but got 1
- Adding an optional parameter breaks existing call sites
- Passing undefined explicitly changes the arity
Possible causes
- A required parameter was omitted or too many arguments were passed
- A callback signature differs from the expected one
- Overload resolution picked a signature the call does not satisfy
Diagnosis steps
Read the expected signature
npx tsc --noEmit 2>&1 | grep TS2554Interpretation
The message states the expected count, letting you compare against the call site.
Inspect the declaration
grep -rn "function name\|name(" src/ | headInterpretation
Seeing the parameter list shows which arguments are optional or required.
Root cause
TypeScript enforces call arity against the resolved signature, counting required parameters. Omitting a required argument, or passing more than the signature accepts, is reported as TS2554.
Fix
Pass the required arguments, mark genuinely optional parameters with `?` or a default, use rest parameters for variadic cases, and update signatures rather than casting the call.
Risk note
Casting the function or using `as any` on the call defeats the arity check and hides real mistakes.
Verify the fix
Run tsc --noEmit and confirm TS2554 is gone; ensure runtime receives the values it needs via a unit test.
Symptoms
The error “TypeScript TS2554 — Expected N Arguments but Got M” points at a specific failure mode. This guide documents the symptoms you can observe, the commands that isolate the cause, the root cause, the fix, and the checks that prove the fix works.
Observed symptoms include:
- error TS2554: Expected 2 arguments, but got 1
- Adding an optional parameter breaks existing call sites
- Passing undefined explicitly changes the arity
Reproduce and Diagnose
Reproduce the failure in isolation before changing any code. Work through the checks below in order; each one narrows the search space.
Step 1: Read the expected signature
npx tsc --noEmit 2>&1 | grep TS2554
The message states the expected count, letting you compare against the call site.
Step 2: Inspect the declaration
grep -rn "function name\|name(" src/ | head
Seeing the parameter list shows which arguments are optional or required.
Likely contributors, in order of frequency:
- A required parameter was omitted or too many arguments were passed
- A callback signature differs from the expected one
- Overload resolution picked a signature the call does not satisfy
Root Cause
TypeScript enforces call arity against the resolved signature, counting required parameters. Omitting a required argument, or passing more than the signature accepts, is reported as TS2554.
The Fix
Pass the required arguments, mark genuinely optional parameters with ? or a default, use rest parameters for variadic cases, and update signatures rather than casting the call.
Watch out: Casting the function or using as any on the call defeats the arity check and hides real mistakes.
function createUser(name: string, age: number, role = 'member'): User { /*...*/ }
// ❌ createUser('alice'); // TS2554: expected 2-3, got 1
createUser('alice', 30); // ✅ default applies
createUser('alice', 30, 'admin'); // ✅ explicit
// rest parameters for variadic
function log(...parts: unknown[]): void { console.log(...parts); }
Verify and Prevent
Run tsc –noEmit and confirm TS2554 is gone; ensure runtime receives the values it needs via a unit test.
Once verified, add a regression test that reproduces the original symptom so the failure cannot silently return.
This class of failure is usually environmental rather than pure logic, so capture the exact command, the environment variables, and the working directory in your bug report. Reproduce it in the smallest possible script, then widen the scope only once the minimal case is understood. A short written checklist for this failure mode saves hours the next time it appears.