typescript应该推断';这';为'型;任何';例如类实例方法?

typescript应该推断';这';为'型;任何';例如类实例方法?,typescript,Typescript,似乎在typescript类的实例方法中,typescript编译器认为“this”与声明类的类型相同 例如: class Person { private name: string; constructor(name) { this.name = name; } public showName() { //Typescript believes 'this' is a 'Person', but it could be any

似乎在typescript类的实例方法中,typescript编译器认为“this”与声明类的类型相同

例如:

class Person {
    private name: string;

    constructor(name) {
        this.name = name;
    }

    public showName() {
        //Typescript believes 'this' is a 'Person', but it could be anything!

        var me: Person = this;

        alert("My name is " + this.name);
    }
}


class Introducer {
    public introduce(person: Person) {
        setTimeout(person.showName, 1);
    }
}

var introducer: Introducer = new Introducer();
var bob = new Person("Bob");

this.name = "Dave";

introducer.introduce(bob);
在showName函数中,键入脚本说明“this”是“Person”。然而,情况并非总是如此——正如介绍器类所示的示例(输出是“我的名字是Dave”,而不是“我的名字是Bob”)


考虑到这种可能性,为什么类实例方法中的“this”类型不是“any”?

编译器合理地假设您将在代码运行时创建的类的范围内。有几种工具可用于确保在该范围内调用方法,包括箭头函数
()=>
调用
应用
。在您描述的情况下,您可以使用它们将方法调用绑定到类上下文

下面是一个使用arrow函数的示例,它为您提供了类保证:

class Person {
    private name: string;

    constructor(name) {
        this.name = name;
    }

    showName = () => {
        //'this' is a definitely a 'Person'

        var me: Person = this;

        alert("My name is " + this.name);
    }
}
尽管我更喜欢在调用方引起范围更改时从调用方解析范围,如下所示:

class Introducer {
    public introduce(person: Person) {
        setTimeout(() => person.showName(), 1);
    }
}

根据您的推理,任何类型都可以删除。在运行时可以绕过静态类型。这不是不使用静态键入的原因。为了补充@Tarh所说的。。。。类型检查是在编码/编译时完成的,它不是呈现代码的一部分,因此,尽管可以用任何东西调用它,但在编译期间它将被检查为
Person
类型。@Brocco:我的问题是,“this”的类型不可能在编译类型上强制执行,因为它的类型未知。那么为什么编译器会假定它是Person呢?静态类型可以在运行时绕过,但这是编译时的问题。因为TypeScript本质上是JavaScript,并且在其上添加了类型,所以它也维护了JS的作用域。这意味着showName函数中的
this
的作用域是类Person,因此为其指定了Person的类型,但是将name设置为Dave的
this
在另一个作用域中,其中
this
不是类型
Person
“这意味着showName函数中的该类的作用域是Person类,因此为其指定了Person类型“-如果我使用fat-arrow/lambda语法,情况就是这样,但我的示例中没有这样做。谢谢!我在TypeScript问题页面上发布了一个关于这个的bug,它被标记为“按设计”。我知道在大多数情况下,它的值都是正确的类型,但我认为这会使它在类型不正确时变得更加混乱。特别是考虑到他们已经实现了专门处理这个问题的语言特性,但是却忽略了类实例函数的问题!