TypeScript似乎发出错误的“this”代码(并且没有警告)

TypeScript似乎发出错误的“this”代码(并且没有警告),typescript,Typescript,他们的GitHub问题似乎非常不希望我提交与此相关的功能请求,所以我将在这里尝试 我有这样的代码: 导出类示例{ 只读myOtherElement:HTMLElement; 公共构造函数{ this.myOtherElement=document.getElementById'myFormElement'; document.querySelectorform.addEventListener'submit',this.sendMessage; } 私有sendMessagee:事件{ this

他们的GitHub问题似乎非常不希望我提交与此相关的功能请求,所以我将在这里尝试

我有这样的代码:

导出类示例{ 只读myOtherElement:HTMLElement; 公共构造函数{ this.myOtherElement=document.getElementById'myFormElement'; document.querySelectorform.addEventListener'submit',this.sendMessage; } 私有sendMessagee:事件{ this.myOtherElement.style.display='none'; } } 通过ES2015输出,这将成为:

示例=类示例{ 建造师{ this.myOtherElement=document.getElementById'myFormElement'; document.querySelectorform.addEventListener'submit',this.sendMessage; } 发送消息{ this.myOtherElement.style.display='none'; } }; 不幸的是,这个代码是错误的。在事件处理程序中,这实际上不再引用类实例;相反,它成为事件的上下文,即发送它的元素。所以这个.myOtherElement实际上是未定义的

现在,这可以用lambda来解决:

document.querySelectorform.addEventListener'submit',e=>this.sendMessagee; 但TypeScript的目的是在运行前捕获更多错误,TypeScript IntelliSense错误地指出sendMessage函数中的this.myOtherElement将指向HtmleElement,因为它的推断与JS不同。当然,如果我相应地更改TypeScript,则不会编译:

私有sendMessagee:事件{ this.style.display='none'; } TypeScript仍然认为这是示例的一个实例,因此出现错误:

错误TS2339 TS属性“样式”在类型“示例”上不存在

在国际海事组织,这两种情况都应该发生:

使用addEventListener'submit',this.sendMessage,编译器应检查sendMessage是否包含对此的任何引用,如果包含,则显示上下文不正确的警告

发出的代码应该不同


我不清楚TypeScript团队是否同意,这只是一个难题?

实际上,发出的代码很好。此函数的上下文可能会根据函数的调用方而变化。正如您所指出的,为了防止这种情况,您可以绑定一个函数,将其绑定到特定的上下文中

所以您要做的是定义一个类成员函数。Typescript无法知道这将更改为什么上下文,因为这是一个运行时更改

sendMessage成员中的内容可以是任何上下文。类上下文、某些调用方上下文等

您可以有另一个成员函数从类上下文调用sendMessage


因此,Typescript无法推断这将是什么上下文,因此无法将其与示例类上下文联系起来。

那么,为什么不向addEventListener函数指针添加一个编译器警告,说明上下文在运行时可能会更改?因为这将应用于每个已定义的函数。每个非lambda函数的上下文取决于此函数的调用方。此行为内置于Javascript中,因此发出警告是没有意义的。此函数指针指向实例方法,但实际上可能不会传递实例上下文。你的意思是让这个方法成为一个静态的方法吗?这里的重点是什么?您正在评论建议的消息。我和Typescript的开发没有任何关系,我只是解释为什么我没有任何意义。如果您要为每个函数发出警告消息,那么最终会出现数千条警告,您和所有使用过的库定义和调用的每个fn都有一条警告。您希望警告Javascript架构决策,这是毫无意义的。您的消息甚至没有帮助,因为独立函数也有这种行为,它们不能是静态的。静态方法也可以更改上下文。