class - Typescript hatası: Bu kapsayıcı tarafından dıştaki 'this' değeri gölgeleniyor
Bir TypeScript sınıfı yöntem bildirimiyle ilgili bir hata aldım, ama hata mesajının hatayla nasıl ilişkilendiğini anlamıyorum.
Mesaj, 'this'in any türünde olduğunu söylüyormuş gibi görünüyor, ama biz bir sınıf tanımı içindeyiz ve bu yüzden 'this'in gerçekten açık olduğunu düşündüm.
Birisi lütfen hata mesajının bu hatayla nasıl bağlantılı olduğunu açıklayabilir mi?
Orijinal yöntem:
calcSize = function() {
return this.width * this.length; // Error on this line
};
// Error text: 'this' implicitly has type 'any' because it does not
//have a type annotation.ts(2683)
//app.ts(39, 16): An outer value of 'this' is shadowed by this container.
düzelt :
calcSize() {
return this.width * this.length;
};
Tam bağlam (düzeltilmiş):
class BaseObject {
constructor(
public width: number = 0,
public length: number = 0
) {}
};
class Rectangle extends BaseObject {
constructor(public width: number = 0, public length: number = 0) {
super(width, length);
}
calcSize() {
return this.width * this.length;
};
}
Cevap #1
TypeScript (ve ES6) içinde iki tür fonksiyon vardır: Klasik function bildirimi ve arrow function. Klasik fonksiyon bildirimi this anahtar kelimesi için varsayılan bağlama mantığına sahipken - arrow function, içinde bulunduğu bağlamın this değerini sürekli olarak kullanacaktır. Örnekte bu, çevreleyen sınıfın örneği olacaktır.
class Rectangle extends BaseObject {
// ..
calcSize = function() {
// The keyword "function" will cause "this" to be floating.
// Since the function is explicitly assigned to calcSize
// (older) TypeScript may not infer the type of "this".
// The value of "this" can be re-bound by changing the context
// using bind or call.
// -> Value of "this" defaults to the class instance
return this.width * this.length; // (potential) type Error on this line
};
calcSizeAsMember () {
// This is also a classic function which will use floating binding
// therefore "this" will be the type of the containing class.
// The value of "this" can be re-bound by changing the context
// using bind or call.
// -> Value of "this" defaults to the class instance
return this.width * this.length;
};
calcSizeAsArrowFunction = () => {
// This is an arrow function which has a constantly-bound "this" keyword,
// it is not possible to re-bind afterward.
// The type of "this" is always the type of the containing class.
// Changing the context using bind or call will have no effect
// -> Value of "this" is always the class instance
return this.width * this.length;
};
};
Cevap #2
Biraz araştırma yaptıktan sonra birkaç ilginç şey buldum. "this", normal bir fonksiyonun (ok fonksiyonu değil) parametresi olabilir ve tipi ya "any" ya da "unknown" olabilir
Fonksiyonu tanımlarken "this" için "any" türüne dikkat edin.
export async function main(this: any) {
try {
console.log(this);
} catch (e: any) {
}
}
