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

foo(...args);

Why am i getting getting this error in Typescript Playground???

Supplied parameters donot match any signature of call target.

4 Answers 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);
Sign up to request clarification or add additional context in comments.

Comments

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

1 Comment

You answered this years ago, but all those issues are now closed and it still isn't possible to do this without your suggestions. I can't figure out why these issues are closed. I didn't read them all, but the one that seemed to be an aggregate of all the others had a last comment that it was going to be pursued and then it was closed.
9
function foo(x:number, y:number, z:number) { 
  console.log(x,y,z);
}
var args:[number, number,number] = [0, 1, 2];
foo(...args);

You can try this. Personally, I think it is the answer that best fits your question scenario.


And Mr.@anask provides a better method, more clear, easier and easier to maintain. This should also be the best practice for TypeScript features.

Use as const to automatically infer static types

Demo in TSPlayground by Mr.@anask

function foo(x: number, y: number, z: number) {
   console.log(x, y, z);
}

// here young !
var args = [0, 1, 2] as const;

foo(...args);

2 Comments

I'd suggest a const assertion like this instead of annotating a tuple, but otherwise this is the correct answer in my opinion.
@jcalz Yes, sir, your method is a better method. Thanks a lot for adding! I will take the liberty to import your answers into the existing answers, and mark your signature. If you open a new independent answer in the future, please let me know; I will restore the reference to your method.
1

Late to the party but You can also:

  • use Parameters to type your args
function foo(x:number, y:number, z:number) { 
   console.log(x,y,z);
}

var args: Parameters<typeof foo> = [0, 1, 2];

foo(...args);

Playground

  • define a type for Args
type Args = [number, number, number]

function foo(...[x,y,z]: Args) { 
   console.log(x,y,z);
}

var args: Args = [0, 1, 2];

foo(...args);

Playground

Of those two I would strongly suggest using separate type for Args, as any change done to this type will be checked against both args and foo.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.