【问题标题】:Should typescript infer 'this' to be of type 'any' for class instance methods?对于类实例方法,打字稿是否应该将“this”推断为“any”类型?
【发布时间】:2015-04-20 19:35:32
【问题描述】:

似乎在 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”的内容。然而,情况并不总是如此——就像 Introducer 类所示的示例一样(输出是“我的名字是 Dave”,而不是“我的名字是 Bob”)。

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

【问题讨论】:

  • 根据您的推理,可以删除任何类型。静态类型可以在运行时被绕过。这不是不使用静态类型的理由。
  • 补充@Tarh所说的......类型检查是在编码/编译时完成的,不是渲染代码的一部分,所以虽然可以用任何东西调用它,但它会被检查在编译期间为 Person 类型。
  • @Brocco:我的问题是“this”的类型不可能在编译类型中强制执行,因为它的类型是未知的。那么为什么编译器会假设它是Person呢?静态类型可以在运行时绕过,但这是一个编译时问题。
  • 因为 TypeScript 本质上是在其上添加类型的 JavaScript,所以它也维护了 JS 的作用域。这意味着 showName 函数中的 this 的作用域是 Person 类,因此赋予它 Person 的类型,但是您将 name 设置为 Dave 的 this 在不同的范围内,其中 this 不是 @ 类型987654326@
  • “这意味着 showName 函数中的 this 的作用域是 Person 类,因此赋予它 Person 的类型”——如果我使用的是 fat-arrow / lambda 语法,情况就是这样,但是在我的示例中,我没有这样做。

标签: typescript


【解决方案1】:

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

这是一个使用箭头函数的示例,这为您提供了类保证:

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);
    }
}

【讨论】:

  • 谢谢!我在 TypeScript 问题页面上发布了一个关于此的错误,它被标记为设计使然。我知道在大多数情况下, this 的值将是正确的类型,但我认为当它不是正确的类型时,它只会让事情变得更加混乱。特别是考虑到他们已经实现了一个语言特性来专门处理这个问题,但是对于类实例函数却忽略了这个问题!
猜你喜欢
  • 1970-01-01
  • 2021-11-25
  • 1970-01-01
  • 2018-06-09
  • 2018-08-12
  • 1970-01-01
  • 2020-04-02
  • 2020-12-20
  • 2016-08-03
相关资源
最近更新 更多