这不是应该正确编译吗?我在突出显示的行中得到一个错误"Property 'hello' does not exist on type 'object'.
"。
我可以毫无问题地访问胖箭头功能之外的g.hello
。
class Test {
constructor() {
}
hello() : string {
return "Hello";
}
}
let g : object;
if (g instanceof Test) {
() => {
g.hello(); ////// ERROR HERE /////
};
}
类型保护对变量(或其他任何东西(进行的收缩不会跨越函数边界。这是一个设计限制。
解决这个问题的一种方法是将g
分配给一个新变量,该变量将根据缩小范围推断其类型。访问箭头功能中的新变量将按预期工作:
class Test {
constructor() {
}
hello() : string {
return "Hello";
}
}
let g : object;
if (g instanceof Test) {
const gTest = g;
() => {
gTest.hello();
};
}
如果g
没有更改,解决此问题的另一种方法是用const
声明g
。这将使编译器保留缩小:
let g : object;
if (g instanceof Test) {
const gTest = g;
() => {
gTest.hello();
};
}
游乐场链接
let+箭头函数
class Test {
constructor() {
}
hello() : string {
return "Hello";
}
}
declare let g : object;
if (g instanceof Test) {
() => {
g.hello(); // error
};
}
当定义函数时g
是Test
,但当函数运行时g
可能不是Test
。
const+箭头函数
class Test {
constructor() {
}
hello() : string {
return "Hello";
}
}
declare const g : object;
if (g instanceof Test) {
() => {
g.hello(); // ok
};
}
g
是不可变的,g
在定义函数后始终是Test
。
const+正则函数
class Test {
constructor() {
}
hello() : string {
return "Hello";
}
}
declare const g : object;
if (g instanceof Test) {
function f() {
g.hello(); // error
};
}
在底层实现中,正则函数f
由ES5var
定义,而不是由ES6let
定义。当g
可能不是Test
时,f
的可变启闭机声明。