为什么布尔值变为真?

Qwe*_*tiy 7 typescript

看看下面的代码:

export class Smth {
  private flag: boolean;

  public update() {
    this.flag = true;

    this.inner();

    if (this.flag === false) { // Operator '===' cannot be applied to types 'true' and 'false'.
      console.log(123);
    }
  }

  private inner() {
    this.flag = false;
  }
}
Run Code Online (Sandbox Code Playgroud)

我无法理解这条线有什么问题

if (this.flag === false)
Run Code Online (Sandbox Code Playgroud)

打字稿说

运算符'==='不能应用于类型'true'和'false'.

但实际上有booleanfalse.

我正在使用typescript 2.6.2但是在线游乐场用2.7显示相同的结果.


它不是运算符''='的公开,不能应用于Typescript 2中的类型x和y,因为该问题是关于比较常量.但在我的代码中,它是一个可查询的类字段,并且有一个函数可以更改值.而且,它被称为.

this.flag = true;

this.inner(); // exectues this.flag = false;

if (this.flag === false) { // ... types 'true' and 'false'. - WHY?
Run Code Online (Sandbox Code Playgroud)

cas*_*raf 5

TypeScript 有点聪明,因为它对你的方法进行静态分析,并且它发现你至少在这个闭包或上下文中false不会分配除之外的任何东西- 这使得类型定义假设你的变量的类型是而不是。它不会查找内部调用方法的更改。falseboolean

将该定义视为全局声明,如下所示:

export type boolean = true | false
Run Code Online (Sandbox Code Playgroud)

whilefalse是只有false,没有truethere 。

有几种解决方案:

  1. 从类声明的一开始就分配类型,如下所示:

    class MyClass {
      private flag: boolean = true
      ...
    }
    
    Run Code Online (Sandbox Code Playgroud)
  2. 只是不要测试直接相等,而是单独使用布尔值:

    if (!this.flag) // instead of this.flag === false
    
    Run Code Online (Sandbox Code Playgroud)


Tit*_*mir 4

您遇到的问题是有关流分析的缺点的更广泛讨论的一部分。您可以在此处阅读一般问题,并在此处阅读与您的问题非常相似的问题。但其要点是:

主要问题是:当调用函数时,我们应该假设它的副作用是什么?一种选择是悲观并重置所有缩小范围,假设任何函数都可能会改变它可能接触到的任何对象。另一种选择是乐观并假设该函数不会修改任何状态。这两个似乎都不好。这个问题涉及局部变量(可能会受到一些“封闭与否”分析)和对象字段的影响。

解决这个问题的简单方法是将常量转换为通用类型。您应该在必要时执行此操作,有人可能会认为该错误具有一定的价值,因为它会警告您可能无法访问的代码,并且可以在出现错误时轻松禁用:

export class Smth {
  private flag: boolean;

  public update() {
    this.flag = true as boolean;

    this.inner();

    if (this.flag === false) { 
      console.log(123);
    }
  }

  private inner() {
    this.flag = false;
  }
}
Run Code Online (Sandbox Code Playgroud)