3

I have this example function:

const spreadingArray(arg1, arg2){ return arg1 + arg2; } const numbers = [4,5]; spreadArray(...numbers); // return 9 spreadArray.apply(this, numbers); // return 9 spreadArray(4, 5); // return 9 

This three examples of function should return the same result. But I have an error running ng serve:

TS2556: Expected 2 arguments, but got 0 or more.

If I comment the first spreadArray(...numbers) and run ng serve it compiles fine, I remove the comment again and it automatically recompile with error but it's already compiled so it keep running and the code works. That make me thing that it's a syntactic error because at the end angular knows how to compiled to es5 wish is .apply(this, numbers) in this case. Note: The problem here is not why I should use spread operator, is why TypeScript doesn't understand it. I want to use it because it's just a Javascript ES6 thing. I'm using @angular/cli 6.1.5, @angular 6.1.4 and I've tasted with node 8.10 and 9.11 and typescript 2.7.2 and 2.9.2.

UPDATE: a real example of this ... function: enter image description here

4
  • You're asking about Typescript; your question has nothing to do with Angular. Commented Aug 31, 2018 at 15:47
  • 5
    As the error is trying to tell you, TypeScript doesn't know how big your array is. Commented Aug 31, 2018 at 15:48
  • Possible duplicate of open-ended function arguments with TypeScript Commented Aug 31, 2018 at 16:04
  • Does this answer your question? TypeScript error when using the Spread operator? Commented Jun 12, 2020 at 0:35

4 Answers 4

2

The problem is about typing.

If you write const numbers = [4,5]; it equals to writing const number: number[] = [4,5] so, when you pass numbers to spreadingArray method, the compiler can not check if you are passing two values or not and give you an exception.

To fix the problem you have to define the correct type for numbers as a two-numbers array:

const numbers: [number, number] = [4,5]; 

Or changing the spreadingArray method in order to accept a spreading attribute:

function spreadingArray(...values: number[]){ return values.reduce((prev, current) => prev + current, 0); } 
Sign up to request clarification or add additional context in comments.

Comments

1

As shared in couples of answers it is not clear what you are trying to achieve from your spreadingArray function, but passing an argument like ...numbers will not meet the requirement of exact two argument of the function.

So, may be you can go for splitting and taking the 0th and 1st Index:

 this.spreadingArray(numbers[0], numbers[1]); // return 9 this.spreadingArray.apply(this, numbers); // return 9 this.spreadingArray(4, 5); // return 9 

Or, you can consider changing your spreadingArray function as below:

spreadingArray(...args:number[]): number { return args.reduce(function(total, number){ return total + number; }, 0); } 

Working Code:

/** TYPESCRIPT CODE class Test { test() { console.log(this.spreadingArray(...numbers)); // return 9 console.log(this.spreadingArray.apply(this, numbers)); // return 9 console.log(this.spreadingArray(4, 5)); // return 9 } spreadingArray(...args:number[]): number { return args.reduce(function(total, number){ return total + number; }, 0); } } const numbers = [4, 5]; let test = new Test(); let button = document.createElement('button'); button.textContent = "Test Output"; button.onclick = function() { test.test(); } document.body.appendChild(button); **/ /** Generated Javascript code **/ var Test = /** @class */ (function() { function Test() {} Test.prototype.test = function() { console.log(this.spreadingArray.apply(this, numbers)); // return 9 console.log(this.spreadingArray.apply(this, numbers)); // return 9 console.log(this.spreadingArray(4, 5)); // return 9 }; Test.prototype.spreadingArray = function() { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } return args.reduce(function(total, number) { return total + number; }, 0); }; return Test; }()); var numbers = [4, 5]; var test = new Test(); var button = document.createElement('button'); button.textContent = "Test Output"; button.onclick = function() { test.test(); }; document.body.appendChild(button);

1 Comment

Ok, let's see a real code. .pipe() function on Observable allow me to pass different functions as parameters could be map, filter. In my case I created an util function that call .pipe(...pipeline) which doesn't know if it's a map or filter functions it just pass with the spread operator. That code runs for others not for me.
0

I'm not an expert on typescript, but it seems the problem is caused because you have 2 parameters on the spreadingArray function but a dynamic number of arguments coming from the function call. Try removing the parameters from your function signature and using the arguments object instead. Docs on arguments can be found here.

const spreadingArray() { return arguments.reduce(function(acc, next) { return acc + next; }, 0); } 

Comments

0

You can override your code to this:

const spreadingArray = (arg1: number, arg2: number, ...args: number[]) => { return arg1 + arg2; } const numbers: [number, number, ...number[]] = [4,5]; spreadingArray(...numbers) 

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.