Reputation: 2653
I have the following enum:
enum EditMode {
View = 0,
Edit = 1,
Delete = 2
}
Let's assume I have a variable of the enum type
var editMode = EditMode.Edit;
Why does the following code not work (goes straight to default)?
switch (editMode) {
case EditMode.Delete:
// ...
break;
case EditMode.Edit:
// ...
break;
default:
// ...
break;
}
Upvotes: 111
Views: 113411
Reputation: 2653
I have found why this happens: somewhere in the code there is a activation function (I am using durandal) which passes this enum as a string (the function has the parameter marked as a enum but still it is a string). This is why my switch statement fails.
I simply converted the value to a number and now everything works as expected.
Upvotes: 31
Reputation: 4136
Change your EditMode enum definition to:
enum EditMode {
View = "View",
Edit = "Edit",
Delete = "Delete"
}
Upvotes: 17
Reputation: 67
Int Enum
enum Sizes {
Small,
Medium,
}
switch (Number(Sizes.Small)) {
case Sizes.Small:
// 👇️ this runs
console.log('size is S');
break;
case Sizes.Medium:
console.log('size is M');
break;
default:
console.log(`non-existent size: ${Sizes.Small}`);
break;
}
String Enum
enum Sizes {
Small = 'S',
Medium = 'M',
}
switch (String(Sizes.Small)) {
case Sizes.Small:
console.log('size is S');
break;
case Sizes.Medium:
console.log('size is M');
break;
default:
console.log(`non-existent size: ${Sizes.Small}`);
break;
}
Upvotes: 1
Reputation: 791
With //@ts-ignore
suppress you can do:
//@ts-ignore
switch (EditMode[editMode] as EditMode) {
case EditMode.Delete:
...
break;
case EditMode.Edit:
...
break;
default:
...
break;
}
}
Upvotes: 2
Reputation: 11
Use it like this.
const enum OperationsType{
CREATE="CREATE",
DELETE="DELETE",
UPDATE="UPDATE"
}
Upvotes: 1
Reputation: 417
If the enum is defined in a separate typescript file, ensure it's marked with "export" and that you import it correctly at the top of the typescript file you're referencing it in.
Upvotes: 1
Reputation: 196
In my case I had the switch inside a condition, which was coercing the enum into a value:
enum A {
VAL_A,
VAL_B,
VAL_C
}
interface ia {
maybe?: A
}
const o: ia = {maybe: 0}
if(o.maybe){ //<-- o.maybe is not falsey (thus, is not 0)
switch(o.maybe) {
case A.VAL_A: //<-- Error! we know that o.maybe is not 0. Its VAL_B | VAL_C
break;
}
}
Upvotes: -1
Reputation: 1271
TypeScript version 3.7.5
this code worked for me
enum Seasons {
Winter,
Spring,
Summer,
Autum
}
switch (+Seasons.Winter) {
case Seasons.Winter:
console.log('weather is cold');
break;
case Seasons.Spring:
console.log('weather is spring');
break;
case Seasons.Summer:
console.log('weather is summer');
break;
default:
break;
}
or you can declare a constant and use as param for switch statement
const season: Seasons = Seasons.Winter
switch (+season) {
case Seasons.Winter:
console.log('weather is cold');
break;
case Seasons.Spring:
console.log('weather is spring');
break;
case Seasons.Summer:
console.log('weather is summer');
break;
default:
break;
}
Upvotes: 12
Reputation: 664
The issue here has to do with typescript's (numeric) literal types. When you do this assignment:
var editMode = EditMode.Edit
TypeScript evaluates the type as:
var editMode: 1 = EditMode.Edit
Now, when you compare a value that typescript knows must be 1
(EditMode.Edit
) to a value that it knows must be 0
(EditMode.View
), it sees all this as a type-safety violation. If the variable editMode
weren't an enum
, typescript would merely complain, but since it's an enum
, which doesn't really exist in javascript, typescript gets to control the transpilation in such a way that it actually throws an error.
So you have 2 options. So you can either coerce editMode
to be a number
or to be an EditMode
(i.e. any of the values EditMode
is permitted to be, not just the one assigned to editMode
the variable).
Personally, I prefer to coerce it to be an EditMode
, because it feels more type-safe.
To go the number route, you can do the following, which was previously mentioned:
switch(+editMode)
To go the EditMode
route (which I recommend), you can pass it to a function as was mentioned, but sometimes it's a little cleaner to not write a function. If that's the case here, then you can again coerce the type in the switch
statement:
switch(editMode as EditMode)
Do whichever you prefer, but I just like the clarity of explicitly saying "this variable is being treated as an EditMode
" as opposed to "this variable is supposed to actually be a number
, not an Enum
".
Upvotes: 26
Reputation: 1572
If you use the switch
expression in a function with typed parameter, this works as expected.
Example:
enum EditMode {
View,
Edit,
Delete,
}
function testSwitch(editMode: EditMode) {
switch(editMode) {
case EditMode.Delete:
console.log("delete");
break;
case EditMode.Edit:
console.log("edit");
break;
default:
console.log("default");
break;
}
}
testSwitch(EditMode.Edit)
will compile 🥳 and output edit
👍
Upvotes: -2
Reputation: 501
In case somebody else ends up here and the above options don't seem to be the issue, double-check that all of your switch statements are breaking/returning! The Typescript compiler is smart enough to see that if your case
cascades through to another one, the value you're comparing on may never hit the case you expect.
let handlerName;
switch(method){
case 'create':
handlerName = 'createHandler';
break;
case 'update';
handlerName = 'updateHandler';
// Here is where the forgotten break would go
default:
throw new Error('Unrecognized Method');
}
switch(handlerName){
case 'createHandler':
...
break;
case 'updateHandler':
// You will see an error on this case because
// the compiler knows that execution will never
// arrive here with handler === 'updateHandler'
default:
throw new Error('Unrecognized Handler');
}
Upvotes: 3
Reputation: 21
Declare your enum using const
:
const enum EditMode {
View = 0,
Edit = 1,
Delete = 2
}
Upvotes: -1
Reputation: 38043
I also had this problem. Easy way to get around it: add a +
sign before your variable in the switch, i.e.
switch (+editMode) {
case EditMode.Delete:
...
break;
case EditMode.Edit:
...
break;
default:
...
break;
}
Upvotes: 123