javascript - TypeScript 如何推断 `this` 的类型?
问题描述
TypeScript 中的推理策略this
让我很困惑,例如:
class A {
s: String
constructor() {
this.s = "this is fine"
}
f() {
console.log(this.s)
}
}
let a = new A
a.f() // -> this is fine
let f1 = (new A).f
f1() // -> undefined
如果你把代码放到 TypeScript Playground中,检查this
inside的类型f()
,你可以看到它被推断为 type this: this
,也就是 的子类型A
。
在这种情况下,我认为这意味着this
绑定到A
,并且不能引用全局对象。否则,this
应推断为 type this: Any
。
但实际上,如 的调用所示f1()
,如果函数f
在 的上下文之外调用A
,它仍然可能是全局对象。
所以在我看来,this
inside的推断类型f()
应该是this: Any
,而不是this: this
。并且只有f
用箭头函数定义的函数才能推断为this: this
. 例如:
class A {
s: String
constructor() {
this.s = "this is fine"
}
f = () => {
console.log(this.s)
}
}
let a = new A
a.f() // -> this is fine
let f1 = (new A).f
f1() // -> this is fine
那么,这是错误还是设计功能?TypeScript 如何推断this
实际的类型?
解决方案
所以在我看来,f() 中 this 的推断类型应该是 this:any,而不是 this:this。
嗯,是。在某些方面你是对的。不能 100% 确定this
类函数内部确实是该类的实例。但打字稿并不意味着 100% 准确!理解这一点很重要!类型保证并非在所有情况下都成立。他们真的做不到。
Javascript 是非常动态的。没有办法只在编译时分析所有这些动态。
所以 Typescript 完全依赖于假设和用户提供的类型信息。它应该对您有所帮助,但当您想自己开枪时,它不会阻止您。
永远不要这样做:
const x = foo.x;
x();
实际上,这具有这样的效果,即旧的类模型然后 ES6 类(如 ember 对象模型)很难与 typescript 一起使用——假设只是站不住脚。即使是最好的打字也有局限性。有些事情你可以在 JS 中做你不能在 TS 中定义。对于所有其他情况,TS 仍然非常有帮助。
推荐阅读
- python - 插入列熊猫中的重复值
- c++ - 无法在 VScode“未定义参考”C++ 中包含 .H 文件
- java - 在更新和删除方法中显示 toast 消息的问题
- python - 如何提取括号内字符串的内容?
- google-chrome - SSRS 2016 在 Chrome 或 Edge 中设置文件夹安全性不起作用
- css - Material ui react 在具有不同css样式的相同输入上设置两个值
- php - 在 laravel 中更改重定向路径
- hadoop - hadoop distcp 相同的子文件夹名称
- vue.js - Vue路由器导航保护添加中间件模块不起作用
- docker - Docker iptables 阻止除域之外的所有流量