Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript TypeScript如何推断“this”的类型?_Javascript_Typescript_Types_This_Type Inference - Fatal编程技术网

Javascript TypeScript如何推断“this”的类型?

Javascript TypeScript如何推断“this”的类型?,javascript,typescript,types,this,type-inference,Javascript,Typescript,Types,This,Type Inference,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 cl

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
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中,并在
f()
中检查
this
的类型,您可以看到它被推断为类型
this:this
,这意味着
A
的子类型

在这种情况下,我认为这意味着
这个
绑定到
一个
,不能引用全局对象。否则,
this
应推断为类型
this:Any

但实际上,如调用
f1()
所示,如果函数
f
A
的上下文之外调用,它仍然可能是全局对象

因此,在我看来,
f()
this
的推断类型应该是
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() // -> undefined
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
那么,这是一个bug还是一个设计特性?TypeScript实际上是如何推断
这个
的类型的

因此,在我看来,f()中这个的推断类型应该是:any,而不是:this

嗯,是的。在某些方面你是对的。不能100%确定类函数中的
这个
是否真的是类的实例。但typescript并不意味着100%准确!理解这一点很重要!类型保证并不适用于所有情况。他们真的不能

Javascript是非常动态的。无法在编译时分析所有这些动态

所以Typescript完全依赖于假设和用户提供的类型信息。它应该会帮助你,但不会阻止你当你想射进自己的脚

永远不要这样做:

const x = foo.x;
x();


实际上,这样做的效果是,较旧的类模型和ES6类(如ember对象模型)很难与typescript一起使用——这些假设根本站不住脚。即使是最好的打字也有局限性。在JS中可以做一些在TS中无法定义的事情。但是TS对所有其他情况都非常有用。

好问题。Typescript有我们称之为不健全的类型系统。(闭包编译器和流也有不健全的类型系统。)不健全的类型系统意味着Typescript有时会为错误的表达式计算类型;它与表达式在运行时将采用的类型不同。正如在另一个回复中提到的,之所以会出现这种情况,是因为JavaScript是非常动态的,并且类型系统设计者采取了一些快捷方式来降低复杂性


在您的特定示例中,即使
这个
确实可以通过
任何
,但实际上它几乎总是
一个
,因此这就是Typescript所选择的。但是,它可能会在
f1()
处发出警告,因为该方法是作为函数调用的(即,没有
this
)。

这是一个错误还是一个设计功能?
它的设计与javascript@JaromandaX谢谢你的提示。我知道,
这个
是由调用站点的上下文动态决定的,按照一定的优先顺序,如一些例子所示。但是我想知道TypeScript是如何静态推断
这个
的类型的。对不起,我明白你现在的问题了。。。因为typescript是类型化的,所以您想知道typescript是如何知道在任何给定的时间该
是什么类型的moment@JaromandaX是的,这正是我想知道的。因为在我给出的示例中,这种行为对我来说是违反直觉的。我要补充的是,在
let f1=(new a).f
上会出现编译错误。