TS2556Semantic Error
Since TS 3.0

Fix TS2556: Spread Argument Must Have Tuple Type

Learn why TypeScript throws TS2556 when spreading arrays into function calls, and how to use tuple types or 'as const' to fix it.

error TS2556: A spread argument must either have a tuple type or be passed to a rest parameter

What This Error Means

TS2556 fires when you try to spread an array into a function call, but TypeScript doesn't know whether the array has the right number of elements. A regular array type like number[] could have zero, one, or a thousand elements — TypeScript can't guarantee it matches the function's parameter count.

To spread safely, TypeScript needs a tuple type (a fixed-length array with known types at each position) or the function must accept a rest parameter (which handles any number of arguments).

// The general shape of the error:
// A spread argument must either have a tuple type or be passed to a rest parameter.

Common Causes

1. Spreading a Regular Array Into a Fixed-Parameter Function

The most common case — you have an array and try to spread it into a function that expects specific parameters.

// ❌ Broken
function createUser(name: string, age: number, email: string) {
  return { name, age, email }
}
 
const userData = ["Alice", 30, "alice@example.com"]
const user = createUser(...userData)
//                      ~~~~~~~~~~~
// Error: A spread argument must either have a tuple type
//        or be passed to a rest parameter.
// ✅ Fixed — use 'as const' to create a tuple
const userData = ["Alice", 30, "alice@example.com"] as const
const user = createUser(...userData)

2. Spreading Function Return Values

When a function returns an array, TypeScript types it as a general array, not a tuple.

// ❌ Broken
function getCoordinates() {
  return [40.7128, -74.006] // TypeScript infers number[]
}
 
function plotPoint(lat: number, lng: number) {
  console.log(`Plotting: ${lat}, ${lng}`)
}
 
plotPoint(...getCoordinates())
//       ~~~~~~~~~~~~~~~~~~~~
// Error: A spread argument must either have a tuple type
//        or be passed to a rest parameter.
// ✅ Fixed — annotate the return type as a tuple
function getCoordinates(): [number, number] {
  return [40.7128, -74.006]
}
 
function plotPoint(lat: number, lng: number) {
  console.log(`Plotting: ${lat}, ${lng}`)
}
 
plotPoint(...getCoordinates())

3. Dynamic Arrays Built With push()

Arrays built dynamically are always typed as general arrays, never tuples.

// ❌ Broken
function formatDate(year: number, month: number, day: number) {
  return `${year}-${month}-${day}`
}
 
const parts: number[] = []
parts.push(2026, 3, 13)
formatDate(...parts)
//         ~~~~~~~~
// Error: A spread argument must either have a tuple type
//        or be passed to a rest parameter.
// ✅ Fixed — declare as a tuple type
const parts: [number, number, number] = [2026, 3, 13]
formatDate(...parts)

How to Fix It

  1. Add as const to the array literal. This is the quickest fix when the values are known at declaration time. It makes the array a readonly tuple:

    const args = [10, "hello"] as const
    myFunction(...args)
  2. Explicitly type the array as a tuple. If you need the array to be mutable or the values aren't known at compile time:

    const args: [number, string] = [10, "hello"]
    myFunction(...args)
  3. Change the function to accept a rest parameter. If the function should handle variable numbers of arguments:

    function logMessages(...messages: string[]) {
      messages.forEach((msg) => console.log(msg))
    }
     
    const msgs = ["hello", "world"]
    logMessages(...msgs) // works — rest parameter accepts any count
  4. Annotate the return type as a tuple when returning fixed-length arrays from functions. TypeScript won't infer tuples automatically from return [a, b].

FAQ

What causes TS2556?

TS2556 occurs because TypeScript can't verify that a spread argument has the correct number of elements for the function being called. A standard array (string[]) has an unknown length, so TypeScript can't guarantee it matches the function's parameter list. TypeScript requires either a tuple type (which has a fixed length and known types) or a rest parameter (which accepts any number of arguments).

How do I fix spread argument must have tuple type?

The most common fix is adding as const after the array literal. This tells TypeScript the array has a fixed length with specific types at each position. If the values are dynamic, explicitly annotate the variable as a tuple type: const pair: [string, number] = [name, age]. Alternatively, refactor the function to use rest parameters if it should accept variable arguments.

When should I use 'as const'?

Use as const when you have a fixed set of literal values that won't change. It makes three things happen: array lengths become fixed, element types become literal types (e.g., "hello" instead of string), and the entire structure becomes readonly. This is perfect for spreading into function calls, defining configuration constants, and anywhere you want TypeScript to infer the narrowest possible type.

Related Errors

Share this reference

Stay Updated

Get the latest TypeScript tips, tutorials, and course updates delivered straight to your inbox.

No spam, unsubscribe at any time.