Why does the logical meaning become true?

Take a look at the 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; } } 

I can’t understand what happened to the line

 if (this.flag === false) 

Typescript says

The operator '===' cannot be applied to the types "true" and "false".

But actually there is boolean and false .

I am using typescript 2.6.2, but the online platform shows the same result with 2.7.


This is not a duplicate. The operator '==' cannot be applied to types x and y in typescript 2 , since this question is about comparing constants. But in my code this is a cool class field, and there is a function that changes the value. Moreover, it is called.

 this.flag = true; this.inner(); // exectues this.flag = false; if (this.flag === false) { // ... types 'true' and 'false'. - WHY? 
+7
typescript
source share
2 answers

The problem you have is part of a broader discussion of the flaws of flow analysis. You can read the general problem here and a very similar problem with yours here . But the point is:

The main question: when a function is called, what should we take for its side effects? One option is to be pessimistic and reset with all the restrictions, assuming that any function can mutate any object that it might fall into. Another option is to be optimistic and assume that the function does not change any state. Both of them seem bad. This problem covers both local (which can be subjected to the analysis of "closed or not"), and objects.

An easy way to get around this is to include the constant in the generic type. You should do it where necessary, you can argue that the error has some significance, as it warns you of possibly inaccessible code and can be easily disabled where it is 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; } } 
+3
source share

TypeScript is pretty smart because it has a static analysis of your method and sees that you never assign anything other than false in this closure or context, which brings the type definition to your type variable false , not boolean . It does not look for changes in internal called methods.

Think of this definition as if it were declared globally as follows:

 export type boolean = true | false 

and false is only false , without true .

There are several solutions:

  • Assign the type from get-go in the class declaration, for example:

     class MyClass { private flag: boolean = true ... } 
  • Just don't check for direct equality, use boolean yourself:

     if (!this.flag) // instead of this.flag === false 
+1
source share

All Articles