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

avatar
Borislav Hadzhiev

Last updated: Feb 28, 2024
3 min

banner

# A spread argument must either have a tuple type or be passed to a rest parameter

The error "A spread argument must either have a tuple type or be passed to a rest parameter" occurs when we use the spread syntax with a function that expects a fixed number of parameters.

To solve the error, use a tuple instead of an array or type the function to use a rest parameter.

Here is an example of how the error occurs.

index.ts
function getObj(name: string, age: number) { return { name, age, }; } // โ›”๏ธ Error: A spread argument must either have a tuple type or be passed to a rest parameter.ts(2556) const result = getObj(...['Bobby Hadz', 30]);

The cause of the error is that the getObj function takes 2 parameters - a string and a number and we're calling it with the result of using the spread syntax (...) on an array.

TypeScript is telling us that there is no guarantee that the array will have exactly 2 elements where the first element is a string and the second is a number.

# Use a const assertion to solve the error

To get around this, you could use a const assertion to pass the array as a tuple.

index.ts
function getObj(name: string, age: number) { return { name, age, }; } const result = getObj(...(['Bobby Hadz', 30] as const));

use const assertion to solve the error

The code for this article is available on GitHub

The as const syntax converts the array to a read-only tuple.

index.ts
// ๐Ÿ‘‡๏ธ const tuple: readonly ["James", 30] const tuple = ['James', 30] as const;

Now that we're using a tuple, TypeScript knows that we're unpacking an array with only 2 elements where the first is a string and the second element is a number.

# Type the array as a tuple to solve the error

You can also explicitly type the array as a tuple to achieve the same result.

index.ts
function getObj(name: string, age: number) { return { name, age, }; } // ๐Ÿ‘‡๏ธ declare tuple instead of array const myTuple: [string, number] = ['Bobby Hadz', 30]; const result = getObj(...myTuple); console.log(result); // ๐Ÿ‘‰๏ธ { name: 'Bobby Hadz', age: 30 }

type array as tuple to solve the error

We declared a tuple with 2 elements - a string and a number. This exactly matches the arguments the function expects to take, so we can use the spread syntax (...) in the function call.

# Using rest parameters to solve the error

An alternative approach is to use rest parameters in the function's definition and change the function to take an indefinite number of parameters.

index.ts
function getArr(...args: string[]) { return args; } const result = getArr(...['James', 'Alice', 'Bobby Hadz', 'Carl']); console.log(result); // ๐Ÿ‘‰๏ธ ['James', 'Alice', 'Bobby Hadz', 'Carl']

using rest parameter to solve the error

The code for this article is available on GitHub

We used a rest parameter in the function's definition.

Rest parameters are used for functions that take an indefinite number of arguments.

You can imagine that the ...args syntax will group the passed-in arguments into an array.

index.ts
function getArr(...args: string[]) { console.log(args); // ๐Ÿ‘‰๏ธ ['James', 'Alice', 'Bobby Hadz', 'Carl'] return args; } const result = getArr(...['James', 'Alice', 'Bobby Hadz', 'Carl']);

The code sample uses the rest arguments syntax (when invoking the getArr function).

The syntax unpacks the array into comma-separated parameters in the function call.

It also uses rest parameters (when defining the function) to group all of the passed-in arguments into an array called args.

I wrote a book in which I share everything I know about how to become a better, more efficient programmer.
book cover
You can use the search field on my Home Page to filter through all of my articles.

Copyright ยฉ 2024 Borislav Hadzhiev