我有以下枚举:
enum EditMode {
View = 0,
Edit = 1,
Delete = 2
}
假设我有一个枚举类型的变量
var editMode = EditMode.Edit;
为什么下面的代码不起作用(直接进入默认)?
switch (editMode) {
case EditMode.Delete:
// ...
break;
case EditMode.Edit:
// ...
break;
default:
// ...
break;
}
我也遇到这个问题了。解决这个问题的简单方法:在开关中的变量之前添加一个
+
符号,即
switch (+editMode) {
case EditMode.Delete:
...
break;
case EditMode.Edit:
...
break;
default:
...
break;
}
我找到了发生这种情况的原因:代码中的某处有一个激活函数(我正在使用 durandal),它将这个枚举作为字符串传递(该函数的参数标记为枚举,但它仍然是一个字符串)。这就是我的 switch 语句失败的原因。
我只是将值转换为数字,现在一切都按预期工作。
这里的问题与打字稿的(数字)文字类型有关。当你做这个作业时:
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
”。
将 EditMode 枚举定义更改为:
enum EditMode {
View = "View",
Edit = "Edit",
Delete = "Delete"
}
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;
}
万一其他人最终来到这里并且上述选项似乎不是问题,请仔细检查所有 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');
}
通过
//@ts-ignore
抑制,您可以执行以下操作:
//@ts-ignore
switch (EditMode[editMode] as EditMode) {
case EditMode.Delete:
...
break;
case EditMode.Edit:
...
break;
default:
...
break;
}
}
如果枚举是在单独的打字稿文件中定义的,请确保它被标记为“导出”,并且在引用它的打字稿文件的顶部正确导入它。
像这样使用它。
const enum OperationsType{
CREATE="CREATE",
DELETE="DELETE",
UPDATE="UPDATE"
}
整数枚举
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;
}
使用
const
声明您的枚举:
const enum EditMode {
View = 0,
Edit = 1,
Delete = 2
}
在我的例子中,我在一个条件内有一个开关,该条件将枚举强制转换为一个值:
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;
}
}
如果您在带有类型参数的函数中使用
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
👍