Why boolean becomes true?

前端 未结 2 1552
清酒与你
清酒与你 2021-01-12 12:00

Take a look at following code:

export class Smth {
  private flag: boolean;

  public update() {
    this.flag = true;

    this.inner();

    if (this.flag          


        
相关标签:
2条回答
  • 2021-01-12 12:28

    The problem you have is part of a broader discussion about the drawbacks of flow analysis. You can read the general problem here and a very similar problem to yours here. But the gist of it is:

    The primary question is: When a function is invoked, what should we assume its side effects are? One option is to be pessimistic and reset all narrowings, assuming that any function might mutate any object it could possibly get its hands on. Another option is to be optimistic and assume the function doesn't modify any state. Both of these seem to be bad. This problem spans both locals (which might be subject to some "closed over or not" analysis) and object fields.

    The simple way to work around this is to cast the constant to the general type. You should do this where necessary, one could argue the error has some value, as it warns you about possibly unreachable code and can be easily disabled where erroneous:

    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;
      }
    }
    
    0 讨论(0)
  • 2021-01-12 12:48

    TypeScript is kinda smart, in that it has a static analysis on your method, and it sees that you never assign anything other than false, at lease in this closure or context - which brings the type definition to assume your variable's type is false and not boolean. It does not look for changes in inner called methods.

    Think of the definition as if it were declared globally like this:

    export type boolean = true | false
    

    while false is only false, without the true there.

    There are several solutions:

    1. Assign the type from the get-go in the class declaration, like so:

      class MyClass {
        private flag: boolean = true
        ...
      }
      
    2. Just don't test for direct equality, use the boolean on its own:

      if (!this.flag) // instead of this.flag === false
      
    0 讨论(0)
提交回复
热议问题