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 OverflowSpread operator with array and object
Typescript spread operator for type - Stack Overflow
Spread operator
Adding arbitrary attributes to object using spread operator
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);
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
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",Can I use the spread operator on class objects which has getter and setter methods for properties? Let’s say I have a class X and a corresponding mongo DB Document DocX
I want to write something like DocX({…Xobj}) but that doesn’t seem to work, it says that some of the props of DocX are not set, but in class X they are get Properties.