Hvad man skal gøre for at bruge spread-operatoren i TypeScript
Jeg har denne eksempel-funktion:
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
Disse tre eksempler på funktion bør give det samme resultat. Men jeg får en fejl, når jeg kører ng serve:
TS2556: Forventede 2 argumenter, men fik 0 eller flere.
Hvis jeg kommenterer den første spreadArray(...numbers) og kører ng serve, kompilerer den fint. Jeg fjerner kommentaren igen, og den kompilere automatisk med fejl, men den er allerede kompileret, så den fortsætter med at køre, og koden virker. Det får mig til at tænke, at det er en syntaksfejl, fordi Angular til sidst ved, hvordan man kompilerer til ES5, hvilket i dette tilfælde er .apply(this, numbers). Bemærk: Problemet her er ikke, hvorfor jeg skal bruge spread-operatoren, men hvorfor TypeScript ikke forstår den. Jeg vil bruge den, fordi det bare er en JavaScript ES6-funktion. Jeg bruger @angular/cli 6.1.5, @angular 6.1.4, og jeg har testet med node 8.10 og 9.11 samt TypeScript 2.7.2 og 2.9.2.
OPDATERING: et ægte eksempel på denne ... funktion: indtast billedbeskrivelse her
Svar #1
Problemet handler om at skrive.
Hvis du skriver const numbers=[4,5]; svarer det til at skrive const number: number[]=[4,5], så når du sender numbers til spreadingArray-metoden, kan compileren ikke tjekke, om du sender to værdier eller ej og giver dig en undtagelse.
For at løse problemet skal du definere den korrekte type for numbers som et array med to tal:
const numbers: [number, number] = [4,5];
Eller ændre spreadingArray-metoden for at acceptere et spredningsattribut:
function spreadingArray(...values: number[]){
return values.reduce((prev, current) => prev + current, 0);
}
Svar #2
Som delt i flere svar er det ikke klart, hvad du prøver at opnå med din spreadingArray-funktion, men at videregive et argument som ...numbers vil ikke opfylde kravet om præcist to argumenter til funktionen.
Så måske kan du vælge at splitte og tage 0. og 1. indeks:
this.spreadingArray(numbers[0], numbers[1]); // return 9
this.spreadingArray.apply(this, numbers); // return 9
this.spreadingArray(4, 5); // return 9
Eller, du kan overveje at ændre din spreadingArray-funktion som nedenfor:
spreadingArray(...args:number[]): number {
return args.reduce(function(total, number){
return total + number;
}, 0);
}
Fungerende kode:
/** 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);