Typescript If语句中的类型脚本类型推断不';不能作为变量工作

Typescript If语句中的类型脚本类型推断不';不能作为变量工作,typescript,Typescript,考虑以下示例: class A {} class B extends A { foo() { return 6; } } const variable: A = new B(); const isValid = variable instanceof B; if (isValid) { variable.foo(); } 调用.foo()会提示以下错误: 这是有意义的,因为变量的类型是A。但是variable.foo()只有在variable是B

考虑以下示例:

class A {}
class B extends A {
    foo() {
        return 6;
    }
}

const variable: A = new B();

const isValid = variable instanceof B;

if (isValid) {
    variable.foo();
}
调用
.foo()
会提示以下错误:

这是有意义的,因为
变量
的类型是
A
。但是
variable.foo()
只有在
variable
B
的实例时才会运行

这样做时,问题不会发生:

class A {}
class B extends A {
    foo() {
        return 6;
    }
}

const variable: A = new B();

if (variable instanceof B) {
    variable.foo();
}
为什么条件存储在变量中而不是显式写入
if
中很重要?

下面有一个建议 (除其他外,请参阅该问题中的链接),以允许将类型保护的结果存储到布尔变量中供以后使用。虽然大多数人都同意这一点,但该语言的首席架构师:

这需要我们跟踪一个变量的特定值对其他变量的影响,这将给控制流分析器增加大量的复杂性(以及相关的性能损失)。不过,我们还是把它作为一个建议


为了进一步扩展这一点,目前编译器认识到,在一个代码块中,
variable instanceof B
已被测试并评估为
true
,而
variable
的类型可以缩小为
B
。。。但在该范围之外,编译器可以“忘记”这种缩小:

if (variable instanceof B) {
    variable.foo(); // okay
}
variable.foo(); // error
为了让类似以下的东西发挥作用:

const isValid = variable instanceof B;

if (isValid) {
  variable.foo(); 
}
本身有效之前,不允许编译器“忘记”缩小范围。。。或者依赖于
是否有效的任何内容都超出范围。从表面上看,这似乎是合理的,但对于每一个这样的情况,如果你需要这样的内存,那么在很多情况下,额外的工作似乎是不必要的。例如,如果您有:

const bar = Math.random() < 0.5 ? { a: 123, b: 456 } : undefined;
const baz = bar?.a;
那么,跟踪这些只是白费力气


有可能将来有人会设计出一种比当前情况更好的方法来实现这一点,而不会使控制流分析变得过于昂贵。也许有人想要在
布尔值
变量上有这样的行为,可以像在相关问题上提到的那样,用类似类型谓词的东西手动注释它

const isValid: variable is B = variable instanceof B; // not valid syntax now

但现在,它不是语言的一部分。如果您对此有强烈的感觉,您可能希望转到相关的GitHub问题,并将您的
instanceof
作为隐式类型保护,但编译器不会通过变量传递这些信息
variable
只是一个布尔值,不再具有类型缩小属性。
const isValid: variable is B = variable instanceof B; // not valid syntax now