Search code examples
typescripttypestypescript-typingstyping

Assigning boolean to number with || operator - strange behaviour


According to typescript type system, cannot be assigned to .

However, having some background with Javascript, I've tried the next batch of code and the result is rather unclear for me:

let booleanVariable: boolean = false;
let numberVariable: number = booleanVariable || 1;
// compiles just fine > numberVariable = 1

If I'm to change '|| 1' to '|| 0', then the compiler error occurs:

let booleanVariable: boolean = false;
let numberVariable: number = 0 || booleanVariable;
// type false is not assignable to number

If I'm to change 'booleanVariable' to 'true', compiler error arises:

let booleanVariable: boolean = true;
let numberVariable: number = booleanVariable|| 1;
// type true is not assignable to type number

And there could be even more adjustment with changing true to false and replacing the order of operands with '||' operator. If someone could explain such behaviour based on aforementioned examples, I would be very grateful.


Solution

  • In the following line, the type of booleanVariable is not boolean but false.

    let booleanVariable: boolean = false;
    

    It seems you can't see the real type by hovering the variable in the playground or your IDE. But if you need to be convinced, you could do:

    const booleanVariable: boolean = false ;
    const tmp = booleanVariable; // Here the type of `tmp` is inferred as `false`
    

    Here is how to declare booleanVariable as a real boolean:

    let booleanVariable = false as boolean;
    

    Now, the next instruction is an error:

    let numberVariable: number = booleanVariable || 1; // Error: Type 'true | 1' is not assignable to type 'number'.
    

    In JavaScript 0 is falsy, then the expression 0 || booleanVariable always returns booleanVariable. So, TypeScript infers that the type of the expression is the type of booleanVariable:

    let numberVariable: number = 0 || booleanVariable; // Error: Type 'boolean' is not assignable to type 'number'.