Typescript 枚举开关将变为默认值而不是正确的大小写

问题描述 投票:0回答:13

我有以下枚举:

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

假设我有一个枚举类型的变量

var editMode = EditMode.Edit;

为什么下面的代码不起作用(直接进入默认)?

switch (editMode) {
    case EditMode.Delete:
        // ...
        break;
    case EditMode.Edit:
        // ...
        break;
    default:
        // ...
        break;
}
enums switch-statement typescript
13个回答
119
投票

我也遇到这个问题了。解决这个问题的简单方法:在开关中的变量之前添加一个

+
符号,即

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

29
投票

我找到了发生这种情况的原因:代码中的某处有一个激活函数(我正在使用 durandal),它将这个枚举作为字符串传递(该函数的参数标记为枚举,但它仍然是一个字符串)。这就是我的 switch 语句失败的原因。

我只是将值转换为数字,现在一切都按预期工作。


21
投票

这里的问题与打字稿的(数字)文字类型有关。当你做这个作业时:

var editMode = EditMode.Edit

TypeScript 将类型计算为:

var editMode: 1 = EditMode.Edit

现在,当你将打字稿知道 must

1
(
EditMode.Edit
) 的值与它知道 must
0
(
EditMode.View
) 的值进行比较时,它会将所有这些视为一种类型 -安全违规。如果变量
editMode
不是
enum
,打字稿只会抱怨,但由于它是一个
enum
,在 javascript 中并不真正存在,打字稿以实际上抛出异常的方式控制转译一个错误。
所以你有两个选择。因此,您可以强制
editMode
number
或为
EditMode
(即允许任何值
EditMode
,而不仅仅是分配给变量
editMode
的值)。
就我个人而言,我更喜欢强制它成为
EditMode
,因为它感觉更类型安全。

要走号码路线,您可以执行以下操作,之前已提到:

switch(+editMode)

要走

EditMode
路线(我推荐),您可以将其传递给前面提到的函数,但有时不编写函数会更干净一些。如果是这种情况,那么您可以再次强制
switch
语句中的类型:

switch(editMode as EditMode)

做你喜欢的任何事情,但我只是喜欢明确地说“这个变量被视为

EditMode
”而不是“这个变量实际上应该是
number
,而不是
Enum
”。


15
投票

将 EditMode 枚举定义更改为:

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

12
投票

TypeScript 版本 3.7.5

这段代码对我有用

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

或者你可以声明一个常量并用作 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;
}


3
投票

万一其他人最终来到这里并且上述选项似乎不是问题,请仔细检查所有 switch 语句是否正在中断/返回! Typescript 编译器足够聪明,可以看到如果您的

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

2
投票

通过

//@ts-ignore
抑制,您可以执行以下操作:

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

1
投票

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


1
投票

像这样使用它。

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

1
投票

整数枚举

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

字符串枚举

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

-1
投票

使用

const
声明您的枚举:

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

-1
投票

在我的例子中,我在一个条件内有一个开关,该条件将枚举强制转换为一个值:

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

}


-2
投票

如果您在带有类型参数的函数中使用

switch
表达式,则这将按预期工作。

示例:

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)

将编译🥳并输出

edit
👍

© www.soinside.com 2019 - 2024. All rights reserved.