Why aren't booleans acting like booleans?

Viewed 185

Using TypeScript 3.9.5 I've encountered TS error:

TS2365: Operator '!==' cannot be applied to types 'false' and 'true'

Simplified example (code doesn't doing anything, but represents the flow of the actual function):

function _huh() {
  let allStatementsMatched = true
  let invoiceIIDsToApply = []

  if (_.isEmpty(invoiceIIDsToApply) === false) {
    invoiceIIDsToApply.forEach(x => {
      if (x.name === 'test') {
        allStatementsMatched = false
      } 
    })

    //  Why does the below statement result in error: TS2365?
    if (allStatementsMatched === false) {

    }
  } 
}

I've found several github issues discussing this, but they all deal with more complex scenarios and I'm unable to see how they apply to my very simple example.

Why is typescript not treating a boolean like a boolean? Where is 'true' and 'false' coming from?

2 Answers

That's happened to me before, but only when I (by mistake) do something like this:

let x: true;
let y: false;
if (x === false) {
  //...whatever...
}

As you can see in the snippet, I am declaring x and y as variables of types true and false instead of assigning the values like below:

let x = true;
let y = false;
if (x === false) {
  //...whatever...
}

Make sure you are not making the same mistake. Sometimes that kind of silly errors are difficult to spot.

I put your code in sandbox and I got

This condition will always return 'false' since the types 'true' and 'false' have no overlap

No big deal, typescript again with its superb flow control analysis tries to outsmart me.

let allStatementsMatched: boolean = true;

Apparently that didn't help. Weird as that would make it quiet as far as this variable is concerned in scope.

let allStatementsMatched = true as boolean;

Looks like true/false doesn't respect explicit type declaration and you have to cast them to make it work.

Related