So there is a little clause you may have missed:

Type checking requires spread elements to match up with a rest parameter.

Without Rest Parameter

But you can use a type assertion to go dynamic... and it will convert back to ES5 / ES3 for you:

function foo(x:number, y:number, z:number) { 
 console.log(x,y,z);
}
var args:number[] = [0, 1, 2];

(<any>foo)(...args);

This results in the same apply function call that you'd expect:

function foo(x, y, z) {
    console.log(x, y, z);
}
var args = [0, 1, 2];
foo.apply(void 0, args);

With Rest Parameter

The alternative is that it all works just as you expect if the function accepts a rest parameter.

function foo(...x: number[]) { 
 console.log(JSON.stringify(x));
}
var args:number[] = [0, 1, 2];

foo(...args);
Answer from Fenton on Stack Overflow
🌐
MDN Web Docs
developer.mozilla.org › en-US › docs › Web › JavaScript › Reference › Operators › Spread_syntax
Spread syntax (...) - JavaScript | MDN
The spread (...) syntax allows an iterable, such as an array or string, to be expanded in places where zero or more arguments (for function calls) or elements (for array literals) are expected. In an object literal, the spread syntax enumerates the properties of an object and adds the key-value ...
Top answer
1 of 4
86

So there is a little clause you may have missed:

Type checking requires spread elements to match up with a rest parameter.

Without Rest Parameter

But you can use a type assertion to go dynamic... and it will convert back to ES5 / ES3 for you:

function foo(x:number, y:number, z:number) { 
 console.log(x,y,z);
}
var args:number[] = [0, 1, 2];

(<any>foo)(...args);

This results in the same apply function call that you'd expect:

function foo(x, y, z) {
    console.log(x, y, z);
}
var args = [0, 1, 2];
foo.apply(void 0, args);

With Rest Parameter

The alternative is that it all works just as you expect if the function accepts a rest parameter.

function foo(...x: number[]) { 
 console.log(JSON.stringify(x));
}
var args:number[] = [0, 1, 2];

foo(...args);
2 of 4
14

I think @Fenton explains it very well but I would like to add some more documentation and possible solutions.

Solutions:

Function overload. I prefer this solution in this case because it keeps some kind of type safety and avoids ignore and any. The original method and function call does not need to be rewritten at all.

function foo(...args: number[]): void
function foo(x: number, y: number, z: number) {
  console.log(x, y, z);
}
var args: number[] = [0, 1, 2];

foo(...args);

Use @ts-ignore to ignore specific line, TypeScript 2.3

function foo(x: number, y: number, z: number) {
  console.log(x, y, z);
}
var args: number[] = [0, 1, 2];
// @ts-ignore
foo(...args);

Use as any.

function foo(x: number, y: number, z: number) {
  console.log(x, y, z);
}
var args: number[] = [0, 1, 2];

(foo as any)(...args);

Link with documentation regarding the spread operator:

https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-1.html

Discussions regarding this:

https://github.com/Microsoft/TypeScript/issues/5296 https://github.com/Microsoft/TypeScript/issues/11780 https://github.com/Microsoft/TypeScript/issues/14981 https://github.com/Microsoft/TypeScript/issues/15375

🌐
GitBook
basarat.gitbook.io › typescript › future-javascript › spread-operator
Spread Operator | TypeScript Deep Dive
The main objective of the spread operator is to spread the elements of an array or object.
🌐
HowToDoInJava
howtodoinjava.com › home › typescript › typescript / javascript spread operator
TypeScript / JavaScript Spread Operator (with Examples)
July 3, 2023 - The spread operator is a new addition to the features available in the JavaScript ES6 version. The spread operator is used to expand or spread an iterable or an array in Typescript or Javascript. 1. When to use the Spread Operator?
🌐
GitHub
github.com › microsoft › TypeScript › issues › 32689
Spread operator for object types and interfaces · Issue #32689 · microsoft/TypeScript
August 2, 2019 - Provide an operator to be used in both {} types and interface types which inherits a set of properties from another object type whilst also allowing for those properties to be selectively overridden.
Published   Aug 02, 2019
🌐
GeeksforGeeks
geeksforgeeks.org › typescript › how-to-use-spread-operator-in-typescript
How to use Spread Operator in TypeScript ? - GeeksforGeeks
July 23, 2025 - The spread operator in TypeScript simplifies array and object manipulation by enabling easy copying, combining, and property modification.
🌐
Tim Mousk
timmousk.com › blog › typescript-spread-operator
How To Use The Spread Operator In TypeScript? – Tim Mouskhelichvili
March 27, 2023 - The spread operator allows to spread or expand iterable objects into individual elements.
Find elsewhere
🌐
Convex
convex.dev › advanced › advanced concepts › spread operator
Spread Operator | TypeScript Guide by Convex
The TypeScript spread operator (...) is a handy feature that can make your code simpler and easier to read. By using it, you can take elements from arrays or properties from objects and spread them into a new array or object.
🌐
Alexey Berezin
blog.beraliv.dev › 2021-07-05-spread-in-typescript
TypeScript spread operator for 2 object types
As I previously said, EcmaScript 6 introduced the spread operator which does the same in JavaScript which we want to achieve here. Let's have an example: ... If we have the same key in both objects, we use if from the second object. Otherwise, we get it from the first object. So let's iterate over all keys of two objects in TypeScript and check whether we have a key in second object.
🌐
+return
plusreturn.com › home › blog › tutorial › 6 awesome tricks with the spread and rest operators in typescript and javascript objects
6 Awesome Tricks with the Spread and Rest Operators in Typescript and Javascript Objects | +return
July 26, 2022 - The (...) spread and rest operators are powerful tools to manipulate your typescript and javascript objects. here are 5 ways for you to get the most out of this operator!
🌐
Upmostly
upmostly.com › home › typescript › simplifying your code with the spread operator
Mastering TypeScript's Spread Operator for Cleaner, More Flexible Code - Upmostly
February 22, 2023 - Firstly, this means that anywhere that is expecting a list of arguments and you have an array, you can use the spread operator to transform your array. This is especially useful in TypeScript’s Math functions, which expect separate arguments rather than numbers:
🌐
Scaler
scaler.com › topics › typescript › tuples-syntax-typescript
Spread syntax with TS tuples - Scaler Topics
April 26, 2023 - It is the opposite of rest syntax, ... a string into its characters. The spread operator in typescript allows an iterable object like an array or a string to expand in places where 0+ arguments are expected....
🌐
Medium
medium.com › geekculture › a-caveat-on-javascripts-spread-operator-with-typescript-38ccc2fa000e
A caveat on JavaScript’s spread operator with TypeScript | by Taufan | Geek Culture | Medium
May 27, 2021 - As highlighted in the introduction to this post, typing in TypeScript just ensures that the value you are passing at least satisfies the type. If you have some more properties in your object value, no problemo! Well, technically there is no problem. Business wise, you might have a hard to trace problem. Imagine the JSON payload includes some other values that you did not expect to be there. Say it includes an ownerId field indicating who can access the resource. If the code blindly spread out the payload to the repository call, anyone can now change the resource ownership.
🌐
Nicotsou
nicotsou.com › tltr-typescript-spread-operator
Master Spread Operator With TypeScript
The spread operator —spoiler alert— can spread the contents of an array or an object.
🌐
Reddit
reddit.com › r/typescript › adding arbitrary attributes to object using spread operator
r/typescript on Reddit: Adding arbitrary attributes to object using spread operator
April 25, 2024 -

Why is it possible to add arbitrary attributes to an object? This should throw a Typescript error in my opinion.

type Params = {
    limit: number;
}

// Does not work
const params: Params = {
    limit: 20,
    q: "john"
}

// Does work
const spreadParams: Params = {
    limit: 20,
    ...({ q: "john" })
};

console.log(spreadParams.q);
// 'john'

https://www.typescriptlang.org/play/?ssl=18&ssc=10&pln=1&pc=1#code/C4TwDgpgBACghgJzgWwM5QLxQN4CgoFQA2AlsicAFxQB2ArsgEYQIDcuAvrrgPQ9QARAPYR0NIcCgB3IQgDWuAMZCaqSWEQpU1eEjSYc+QqXJUoAJgAMAGiMEAjtQBEAKyEALGk87c+gkegy8koqalCoYAgQcAAmulo6mvpYeITEZBTUVrZpAHT5ABTYUI5Qrh5eUBwAlJzsIapCRBC5REIA5gURUbHxaLn21ex+AORuniO4QA

🌐
Reddit
reddit.com › r/typescript › spread operator with array and object
r/typescript on Reddit: Spread operator with array and object
April 27, 2022 -

Edit: This seems to be an issue since 2016, and apparently, no fix (yet? since 2016) because it seems like just an edge case.

Hi all, I accidentally mistyped [ with { at line 4 in the code below and it passes compiler check. Should this happen and why does it behave like that?

        type Foo = number // just an example
        
        let t: Foo[] = [] // [1,2,3] 
        let c: Foo[] = {...t}
        console.log(c.map(e=>-e))

It took me a few minutes in a sea of code to realise what's wrong. Needless to say, it was quite frustrating, I'm sorry if this is a stupid question.

playground link

here is my tsconfig.json

        {
          "compilerOptions": {
            "target": "es5",
            "lib": [
              "dom",
              "dom.iterable",
🌐
TypeScript
typescriptlang.org › docs › handbook › release-notes › typescript-3-0.html
TypeScript: Documentation - TypeScript 3.0
TypeScript 3.0 adds support to multiple new capabilities to interact with function parameter lists as tuple types. TypeScript 3.0 adds support for: Expansion of rest parameters with tuple types into discrete parameters. Expansion of spread expressions with tuple types into discrete arguments.
🌐
Execute Program
executeprogram.com › courses › everyday-typescript › lessons › object-spread
Everyday TypeScript: Object Spread
Learn programming languages like TypeScript, Python, JavaScript, SQL, and regular expressions. Interactive with real code examples.