Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does a switch statement on an enum throw 'not comparable to type' error?

While doing a Lynda tutorial on Typescript ( https://www.lynda.com/Visual-Studio-tutorials/TypeScript-types-part-2/543000/565613-4.html#tab ), I hit a snag. The sample code illustrates how switch statements work in TypeScript but the code that seems to work fine for the instructor throws a Type 'x' is not comparable to type 'y' error. Here's the code:

enum temperature{
    cold,
    hot
}

let temp = temperature.cold;

switch (temp) {
    case temperature.cold:
        console.log("Brrr....");
        break;
    case temperature.hot:
        console.log("Yikes...")
        break;
}

I get an error and squiggles under case temperature.hot: saying:

Type 'temperature.hot' is not comparable to type 'temperature.cold'

What gives?

like image 869
Horkin Avatar asked Jul 19 '17 17:07

Horkin


3 Answers

That's because the compiler already knows that the case temperature.hot will never happen: the variable temp is given the enum literal type temperature.cold, which can only be assigned that value itself (or null if there are no strict null checks). As temperature.hot is not a compatible value here, the compiler throws an error.

If we discard the information about the literal (by casting or retrieving the value from a function):

function how_cold(celsius: number): temperature {
    return celsius > 40 ? temperature.hot : temperature.cold;
}

The code will then compile:

let temp = how_cold(35); // type is "temperature"

switch (temp) {
    case temperature.cold:
        console.log("Brrr....");
        break;
    case temperature.hot:
        console.log("Yikes...")
        break;
}

Alternatively, prepending + to the value works because it converts the value to a number, which will also widen the type's scope and make it compatible with all enum variants, as well as other numbers.

let temp = temperature.cold;

switch (+temp) {
    case temperature.cold:
        console.log("Brrr....");
        break;
    case temperature.hot:
        console.log("Yikes...")
        break;
    case 5:
        console.log("What??");
        break;
}
like image 151
E_net4 stands with Ukraine Avatar answered Nov 17 '22 13:11

E_net4 stands with Ukraine


Another possible reason could be if you check if the enum variable is not null but this also triggers if enumVal is 0. This only holds true if the enum has the default numeric values (so first item gets the value of 0)

if (!!enumVal) {
    switch (enumVal) {
         case EnumClass.First // the if clause automatically excludes the first item
like image 8
Kris Jobs Avatar answered Nov 17 '22 13:11

Kris Jobs


In my case the problem was as @Kris mentioned.
I had to add

if (icon !== null) {
    switch (icon) {

or change the first value of the enum to be 1 instead of 0

export enum ICON_TYPE {
    ICON_A = 1,
    ICON_B = 2
}
like image 2
Tals Avatar answered Nov 17 '22 11:11

Tals