Typescript: Type "boolean" is not comparable to type "number"

Viewed 5648

I must be missing something. I have this function:

  transform(value: number): string {
    switch (value) {
      case value > 1 && value < 86400:
        return 'this';
        break;
      case value > 86401 && value <  259200:
        return 'that';
        break;
    }
  }

When I try to compile it, I get these errors:

ERROR in src/app/time-transform.pipe.ts:10:12 - error TS2678: Type 'boolean' is not comparable to type 'number'.

10       case value > 1 && value < 86400:
              ~~~~~~~~~~~~~~~~~~~~~~~~~~
src/app/time-transform.pipe.ts:13:12 - error TS2678: Type 'boolean' is not comparable to type 'number'.

13       case value > 86401 && value <  259200:
              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

I want to be able to compare numbers. What am I missing here?

2 Answers

That is because for switch/case uses strict comparison, i.e. ===, and you are comparing value, which is a number, against an expression, e.g. value > 1 && value < 86400 that is evaluated as boolean.

You should be using if/else statements instead. Note that your switch/case code does not have a default return, which will throw an error anyway: you will need to catch causes where value <= 1 and value >= 259200 anyway:

transform(value: number): string {
    if (value > 1 && value < 86400) {
        return 'this';
    } else if (value > 86401 && value < 259200) {
        return 'that';
    } else {
        return 'something else';
    }
}

For the sake of clarity. There are two different elements in a switch/case which will be compared. The first element is what you wrote after the 'switch' keyword in the in parentheses (which is a number in your case). The second element are those elements that you wrote after the 'case' keywords which are conditional statements in your case. Therefore these statements' result will be always boolean after parsing them. This means you want to compare a number to a boolean eventually. Well, the result of this comparison is always false because of the strict comparison used by switch/case.

switch (value) { // <-- First member of comparison (number)
    
      case value > 1 && value < 86400: /* <-- Second member of comparison 
      which will be a boolean after parsing it */
        return 'this';
        break;
      }
      
      /* Well you are trying to do that: 3 === true,
      but this is always false because of the strict comparison (===)       */

A possible workaround (not really beautiful solution):

switch (true) { /* Use 'true' as the first member of the comparison 
and your code will be executed in those case 
when the condition evaluation is true in the 'case' block */
      case value > 1 && value < 86400:
        return 'this';
        break;
      }

Related