简体   繁体   English

打字稿枚举开关不起作用

[英]Typescript enum switch not working

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;
    }

I also had this problem.我也有这个问题。 Easy way to get around it: add a + sign before your variable in the switch, ie绕过它的简单方法:在 switch 中的变量前添加一个+号,即

switch (+editMode) {
    case EditMode.Delete:
        ...
        break;
    case EditMode.Edit:
        ...
        break;
    default:
        ...
        break;
    }

i have found why i does happen.我找到了为什么我会发生。 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).代码中的某处有一个激活函数(我正在使用 durandal),它将此枚举作为字符串传递(该函数将参数标记为枚举,但它仍然是一个字符串)。 this is why my switch statement fails.这就是我的 switch 语句失败的原因。 i simply converted the value to a number and now everything works as expected.我只是将值转换为数字,现在一切都按预期工作。 thanks anyways不管怎么说,多谢拉

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: TypeScript 将类型评估为:

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.现在,当您将 typescript 知道必须1 ( EditMode.Edit ) 的值与它知道必须0 ( EditMode.View ) 的值进行比较时,它会将所有这些视为违反类型安全。 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.如果变量editMode不是enumeditMode只会抱怨,但由于它是enum ,它实际上并不存在于 javascript 中,因此 typescript 可以以这样一种方式控制转译,它实际上会引发错误。
So you have 2 options.所以你有2个选择。 So you can either coerce editMode to be a number or to be an EditMode (ie any of the values EditMode is permitted to be, not just the one assigned to editMode the variable).因此,您可以将editMode强制为number或将其强制为EditMode (即允许EditMode任何值,而不仅仅是分配给editMode变量的值)。
Personally, I prefer to coerce it to be an EditMode , because it feels more type-safe.就个人而言,我更喜欢将其强制为EditMode ,因为它感觉更类型安全。

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.要使用EditMode路线(我推荐),您可以将其传递给前面提到的函数,但有时不编写函数会更简洁一些。 If that's the case here, then you can again coerce the type in the switch statement:如果是这种情况,那么您可以再次强制switch语句中的类型:

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 ".做你喜欢的任何事情,但我只是喜欢明确地说“这个变量被视为EditMode ”而不是“这个变量实际上应该是一个number ,而不是一个Enum ”。

TypeScript version 3.7.5打字稿版本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或者您可以声明一个常量并用作 switch 语句的参数

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;
}

在此处输入图片说明

Change your EditMode enum definition to:将您的 EditMode 枚举定义更改为:

enum EditMode {
    View = "View",
    Edit = "Edit",
    Delete = "Delete"
}

Typescript 3.6.3打字稿 3.6.3

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!如果其他人在这里结束并且上述选项似乎不是问题,请仔细检查您的所有 switch 语句是否中断/返回! 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. Typescript 编译器足够聪明,可以看到如果您的case级联到另一个case ,您正在比较的值可能永远不会达到您期望的案例。

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');
}

Use it like this.像这样使用它。

const enum OperationsType{
    CREATE="CREATE",
    DELETE="DELETE",
    UPDATE="UPDATE"
}

With //@ts-ignore suppress you can do:使用//@ts-ignore抑制,您可以执行以下操作:

//@ts-ignore
switch (EditMode[editMode] as EditMode) {
    case EditMode.Delete:
        ...
        break;
    case EditMode.Edit:
        ...
        break;
    default:
        ...
        break;
    }
}

如果枚举是在单独的打字稿文件中定义的,请确保它标有“导出”,并且您在引用它的打字稿文件的顶部正确导入它。

If you use the switch expression in a function with typed parameter, this works as expected.如果您在带有类型参数的函数中使用switch表达式,这将按预期工作。

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 👍将编译🥳并输出edit 👍

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;
    }

}

Declare your enum using const :使用const声明您的枚举:

const enum EditMode {
    View = 0,
    Edit = 1,
    Delete = 2
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM