จะทำอย่างไรเพื่อใช้โอเปอเรเตอร์กระจายใน TypeScript
ฉันมีฟังก์ชันตัวอย่างนี้:
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
ตัวอย่างฟังก์ชันสามตัวนี้ควรให้ผลลัพธ์เดียวกัน แต่ฉันพบข้อผิดพลาดเมื่อตอนรัน ng serve:
TS2556: คาดว่าจะมีอาร์กิวเมนต์ 2 ตัว แต่ได้รับ 0 ตัวหรือมากกว่า
ถ้าผมคอมเมนต์ spreadArray(...numbers) ตัวแรกและรัน ng serve มันคอมไพล์ได้ปกติ ผมเอาคอมเมนต์ออกอีกครั้งมันก็จะคอมไพล์ใหม่โดยอัตโนมัติพร้อมกับมีข้อผิดพลาด แต่เนื่องจากมันคอมไพล์ไปแล้ว ดังนั้นมันก็ยังคงรันต่อและโค้ดใช้งานได้ ซึ่งทำให้ผมคิดว่ามันเป็นข้อผิดพลาดด้านไวยากรณ์ เพราะท้ายที่สุด Angular รู้วิธีคอมไพล์เป็น es5 ซึ่งในกรณีนี้คือ .apply(this, numbers) หมายเหตุ: ปัญหาที่นี่ไม่ใช่ทำไมผมควรใช้ spread operator แต่เป็นทำไม TypeScript ถึงไม่เข้าใจ ผมอยากใช้มันเพราะมันเป็นของ Javascript ES6 ผมใช้ @angular/cli 6.1.5, @angular 6.1.4 และได้ทดลองกับ node 8.10 และ 9.11 และ typescript 2.7.2 และ 2.9.2
อัปเดต: ตัวอย่างจริงของฟังก์ชัน ... นี้: ใส่คำอธิบายภาพที่นี่
คำตอบ #1
ปัญหาคือเกี่ยวกับการพิมพ์
ถ้าคุณเขียน const numbers=[4,5]; มันเท่ากับการเขียน const number: number[]=[4,5] ดังนั้น เมื่อคุณส่ง numbers ไปยังเมธอด spreadingArray คอมไพเลอร์จะไม่สามารถตรวจสอบได้ว่าคุณส่งค่ามาสองค่าหรือไม่ และจะทำให้เกิดข้อยกเว้น
ในการแก้ปัญหานี้ คุณต้องกำหนดชนิดที่ถูกต้องสำหรับ numbers เป็นอาร์เรย์ของตัวเลขสองตัว:
const numbers: [number, number] = [4,5];
หรือการเปลี่ยนแปลงเมธอด spreadingArray เพื่อให้สามารถรับแอตทริบิวต์การกระจายได้:
function spreadingArray(...values: number[]){
return values.reduce((prev, current) => prev + current, 0);
}
คำตอบ #2
ตามที่ได้แชร์ในคำตอบบางส่วน ยังไม่ชัดเจนว่าคุณพยายามจะทำอะไรจากฟังก์ชัน spreadingArray ของคุณ แต่การส่งอาร์กิวเมนต์เช่น ...numbers จะไม่ตรงตามข้อกำหนดของการมีอาร์กิวเมนต์สองตัวที่แน่นอนของฟังก์ชัน
ดังนั้น คุณอาจจะแยกและนำดัชนีที่ 0 และ 1 ไปใช้ได้:
this.spreadingArray(numbers[0], numbers[1]); // return 9
this.spreadingArray.apply(this, numbers); // return 9
this.spreadingArray(4, 5); // return 9
หรือคุณสามารถพิจารณาเปลี่ยนฟังก์ชัน spreadingArray ของคุณดังนี้:
spreadingArray(...args:number[]): number {
return args.reduce(function(total, number){
return total + number;
}, 0);
}
โค้ดที่ทำงานได้:
/** 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);