typescript - ทำไม `this` ถึงถูกพิมพ์เป็น `any` ภายในฟังก์ชัน?
ถ้าฉันมีฟังก์ชันในโมดูล, TypeScript อนุญาตให้ฉันทำอะไรบางอย่างเช่น this.unexistingFunction(); (ซึ่ง unexistingFunction ไม่มีอยู่จริง). สิ่งนี้เกิดขึ้นเพราะ this มีชนิดเป็น any ภายในฟังก์ชัน
ทำไมเป็นเช่นนั้น? ในบริบทนี้ไม่มีเหตุผลที่ this จะถูกพิมพ์เป็น any และมันมีแนวโน้มที่จะเกิดข้อผิดพลาดได้ง่าย ตัวอย่างเช่น ถ้าฉันพิมพ์ผิดเป็น this.myFunction(); แทนที่จะเป็นเพียง myFunction(); เพื่อเรียกฟังก์ชันในท้องถิ่น ตัวคอมไพเลอร์ก็จะปล่อยให้ทำแบบนั้นได้ แม้ว่า this.myFunction(); จะไม่อยู่จริงก็ตาม
คำตอบ #1
คุณสามารถเปิดใช้งานตัวเลือก --noImplicitThis true เพื่อจำกัด this ที่มีประเภท any (this:any จะไม่ถูกอนุญาต)
ตัวอย่าง :
class Rectangle {
//private w: number; //uncomment this line
//private h: number; //uncomment this line
constructor(w, h) {
this.w = w;
this.h = h;
}
getAreaFunction() {
return () => {
return this.w * this.h;
};
}
}
let rectangle = new Rectangle(2, 5);
let areaFunction = rectangle.getAreaFunction();
let area = areaFunction();
console.log(area);
หมายเหตุ: คอมไพล์ด้วย tsc --noImplicitThis
ตรวจสอบสิ่งนี้จาก Typescript Playground
คำตอบ #2
นี่น่าจะเกิดขึ้นเพราะคุณไม่ได้ bind ฟังก์ชันของคุณ ใน JS รวมถึงใน TypeScript ค่า this จะถูกกำหนดโดยผู้เรียกใช้งาน ไม่ใช่ผู้ประกาศ
ซึ่งหมายความว่า ถ้าคุณส่ง callback ระหว่างวัตถุแบบนี้:
const a = {
a: function() {console.log(this)}
}
const b = {
b: a.a
}
b.b(); // `this` inside the function will be the instance of `b`, not `a` where it was declared.
สาเหตุทำให้คอมไพเลอร์ TypeScript ไม่สามารถรู้ได้ว่าฟังก์ชันจะถูกเรียกใช้งานที่ใดในเวลาคอมไพล์ ดังนั้นจึงไม่สามารถให้ข้อมูลประเภทได้ ในการแก้ไขปัญหานี้ คุณควร bind ฟังก์ชันนั้น:
class a {
constructor() {
a = a.bind(this);
}
/* rest of class */
}
หรือใช้ฟังก์ชันลูกศร:
class a {
const a = () => {};
}
ซึ่งผูกโดยอัตโนมัติเข้ากับบริบทที่ถูกต้อง
