TypeScript "this" 范围问题

TypeScript "this" issue with scope

我的代码片段:

class MyClass {
    name = "MyClass";

    // traditional method definition
    getName1(){
        return this.name;
    }

    // method defined as an arrow function
    getName2 = () => {
        return this.name;
    }

    // traditional method definition using a this parameter
    getName3(this: MyClass){
        return this.name;
    }
}

const c = new MyClass();
const obj = {
    name: "obj",
    getName1: c.getName1,
    getName2: c.getName2,
    getName3: c.getName3
};

const g = c.getName3;

console.log(c.getName1());
// "MyClass" because this is called in the context of c
// using a traditional method definition getName1

console.log(c.getName2());
// "MyClass" because this is called in the context of c
// using an arrow function getName2

console.log(c.getName3());
// "MyClass" because this is called in the context of c
// using a traditional method definition getName3, having
// a this parameter that statically enforce the context of c

console.log(obj.getName1()); 
// "obj" because this is called in the context of obj
// using the MyClass traditional method definition getName1()
// and assigning it to obj's getName1 property

console.log(obj.getName2()); 
// "MyClass" because this is called in the context of obj
// using an arrow function getName2 and assigning it 
// to obj's getName2 property, but which will preserve c's context
// nonetheless

console.log(obj.getName3()); 
// "obj" but why? Isn't the context of this enforced as that of MyClass? Shouldn't I get
// « The 'this' context of type 'obj' is not assignable to method's 'this' of type 'MyClass' »

console.log(g()); 
// Error, the 'this' context of type 'void' is not assignable to method's 'this' of type 'MyClass'.
// but isn't g declared in the global this context?

我的问题在评论中突出显示,但我还是将它们列如下:

  1. 为什么console.log(obj.getName3());显示"obj"this 的上下文是否与 MyClass 的上下文一样强制执行?我不应该得到类似的东西吗:

The 'this' context of type 'obj' is not assignable to method's 'this' of type 'MyClass'

  1. 我知道 g 不是在 object/class 的上下文中声明的,而是在全局对象上下文中声明的,因此 this 应该指globalThis?如果是这样,那为什么我会得到以下信息:

The 'this' context of type 'void' is not assignable to method's 'this' of type 'MyClass'.

我认为打字稿将“外部”对象推断为 this,因此您可以从 obj.getName3() 获得“obj”,这没问题,因为它也与 class 匹配。它有名称 attr 和所有方法,所以没问题。

如果您将 obj.name 更改为 obj.noname(或 fn 名称之一),您将无法调用 obj.getName3(),因为 obj 不再与 class 匹配.

g() 也是如此。 g 的外部对象是 void 并且没有名称属性(和 fns),因此您会收到其他错误消息。

阅读更多:https://www.typescriptlang.org/docs/handbook/2/functions.html#declaring-this-in-a-function