为什么布尔值变为真?

时间:2018-02-05 16:01:49

标签: typescript

请查看以下code

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;
  }
}

我无法理解该行

的错误
if (this.flag === false)

打字稿说

  

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

但实际上有booleanfalse

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

这不是Operator '==' cannot be applied to types x and y in Typescript 2的共同体,因为这个问题是关于比较常数。但在我的代码中,它是一个可查询的类字段,并且有一个函数可以更改值。而且,它被称为。

this.flag = true;

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

if (this.flag === false) { // ... types 'true' and 'false'. - WHY?

2 个答案:

答案 0 :(得分:4)

您遇到的问题是关于流量分析缺点的更广泛讨论的一部分。您可以阅读常规问题here以及与您here非常相似的问题。但它的要点是:

  

主要问题是:当调用一个函数时,我们应该假设它的副作用是什么?   一种选择是悲观并重置所有缩小,假设任何函数可能会改变它可能会触及的任何对象。另一种选择是乐观并假设该功能不会修改任何状态。这两个似乎都很糟糕。   这个问题跨越了两个本地人(可能受某些“关闭或不关闭”分析)和对象字段。

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

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;
  }
}

答案 1 :(得分:1)

TypeScript有点聪明,因为它对您的方法进行了静态分析,并且它发现您在此闭包或上下文中至少不会分配false以外的任何内容 - 这使得类型定义假设您的变量类型为false而不是boolean。它不寻找内部被调用方法的变化。

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

export type boolean = true | false

虽然false仅为false,但true没有。{/ p>

有几种解决方案:

  1. 在类声明中从get-go中分配类型,如下所示:

    class MyClass {
      private flag: boolean = true
      ...
    }
    
  2. 只是不测试直接相等,自己使用布尔值:

    if (!this.flag) // instead of this.flag === false