打字稿枚举开关不起作用
Typescript enum switch not working
我有以下枚举
enum EditMode {
View = 0,
Edit = 1,
Delete = 2
}
假设我有一个枚举类型的变量
var editMode = EditMode.Edit;
为什么下面的代码不起作用(直接进入默认)?
switch (editMode) {
case EditMode.Delete:
...
break;
case EditMode.Edit:
...
break;
default:
...
break;
}
我找到了为什么会这样。代码中某处有一个激活函数(我正在使用 durandal),它将此枚举作为字符串传递(该函数的参数标记为枚举,但它仍然是一个字符串)。这就是我的 switch 语句失败的原因。我只是将值转换为数字,现在一切都按预期进行。无论如何谢谢
我也遇到了这个问题。绕过它的简单方法:在开关中的变量之前添加一个 +
符号,即
switch (+editMode) {
case EditMode.Delete:
...
break;
case EditMode.Edit:
...
break;
default:
...
break;
}
使用 const
:
声明枚举
const enum EditMode {
View = 0,
Edit = 1,
Delete = 2
}
万一其他人在这里结束并且上述选项似乎不是问题,double-check 你所有的 switch 语句都是 breaking/returning! 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');
}
将您的 EditMode 枚举定义更改为:
enum EditMode {
View = "View",
Edit = "Edit",
Delete = "Delete"
}
打字稿 3.6.3
如果您在带类型参数的函数中使用 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
这里的问题与 typescript 的 (numeric) literal types 有关。当你做这个作业时:
var editMode = EditMode.Edit
TypeScript 将类型计算为:
var editMode: 1 = EditMode.Edit
现在,当您将 typescript 知道的值 must 与 知道的值 1
(EditMode.Edit
) 进行比较时must be 0
(EditMode.View
),它将所有这些视为类型安全违规。如果变量 editMode
不是 enum
,打字稿只会抱怨,但由于它是一个 enum
,它在 javascript 中并不存在,打字稿可以控制以实际抛出错误的方式进行转译。
所以你有两个选择。因此,您可以强制 editMode
成为 number
或成为 EditMode
(即任何值 EditMode
都可以是,而不仅仅是分配给 EditMode
的值=18=] 变量)。
就个人而言,我更喜欢将其强制转换为 EditMode
,因为它感觉类型更安全。
要走数字路线,您可以执行以下操作,前面提到过:
switch(+editMode)
要走 EditMode
路线(我推荐),您可以将它传递给前面提到的函数,但有时不编写函数会更简洁一些。如果是这种情况,那么您可以再次强制 switch
语句中的类型:
switch(editMode as EditMode)
随心所欲,但我喜欢明确地说 "this variable is being treated as an EditMode
" 而不是 "this variable is supposed to actually be a number
, not an Enum
"。
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;
}
在我的例子中,我在一个条件中设置了开关,它将枚举强制转换为一个值:
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;
}
}
如果枚举是在单独的 typescript 文件中定义的,请确保它被标记为 "export" 并且您在引用它的 typescript 文件的顶部正确导入它。
像这样使用它。
const enum OperationsType{
CREATE="CREATE",
DELETE="DELETE",
UPDATE="UPDATE"
}
使用 //@ts-ignore
抑制你可以做:
//@ts-ignore
switch (EditMode[editMode] as EditMode) {
case EditMode.Delete:
...
break;
case EditMode.Edit:
...
break;
default:
...
break;
}
}
我有以下枚举
enum EditMode {
View = 0,
Edit = 1,
Delete = 2
}
假设我有一个枚举类型的变量
var editMode = EditMode.Edit;
为什么下面的代码不起作用(直接进入默认)?
switch (editMode) {
case EditMode.Delete:
...
break;
case EditMode.Edit:
...
break;
default:
...
break;
}
我找到了为什么会这样。代码中某处有一个激活函数(我正在使用 durandal),它将此枚举作为字符串传递(该函数的参数标记为枚举,但它仍然是一个字符串)。这就是我的 switch 语句失败的原因。我只是将值转换为数字,现在一切都按预期进行。无论如何谢谢
我也遇到了这个问题。绕过它的简单方法:在开关中的变量之前添加一个 +
符号,即
switch (+editMode) {
case EditMode.Delete:
...
break;
case EditMode.Edit:
...
break;
default:
...
break;
}
使用 const
:
const enum EditMode {
View = 0,
Edit = 1,
Delete = 2
}
万一其他人在这里结束并且上述选项似乎不是问题,double-check 你所有的 switch 语句都是 breaking/returning! 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');
}
将您的 EditMode 枚举定义更改为:
enum EditMode {
View = "View",
Edit = "Edit",
Delete = "Delete"
}
打字稿 3.6.3
如果您在带类型参数的函数中使用 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
这里的问题与 typescript 的 (numeric) literal types 有关。当你做这个作业时:
var editMode = EditMode.Edit
TypeScript 将类型计算为:
var editMode: 1 = EditMode.Edit
现在,当您将 typescript 知道的值 must 与 知道的值 1
(EditMode.Edit
) 进行比较时must be 0
(EditMode.View
),它将所有这些视为类型安全违规。如果变量 editMode
不是 enum
,打字稿只会抱怨,但由于它是一个 enum
,它在 javascript 中并不存在,打字稿可以控制以实际抛出错误的方式进行转译。
所以你有两个选择。因此,您可以强制 editMode
成为 number
或成为 EditMode
(即任何值 EditMode
都可以是,而不仅仅是分配给 EditMode
的值=18=] 变量)。
就个人而言,我更喜欢将其强制转换为 EditMode
,因为它感觉类型更安全。
要走数字路线,您可以执行以下操作,前面提到过:
switch(+editMode)
要走 EditMode
路线(我推荐),您可以将它传递给前面提到的函数,但有时不编写函数会更简洁一些。如果是这种情况,那么您可以再次强制 switch
语句中的类型:
switch(editMode as EditMode)
随心所欲,但我喜欢明确地说 "this variable is being treated as an EditMode
" 而不是 "this variable is supposed to actually be a number
, not an Enum
"。
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;
}
在我的例子中,我在一个条件中设置了开关,它将枚举强制转换为一个值:
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;
}
}
如果枚举是在单独的 typescript 文件中定义的,请确保它被标记为 "export" 并且您在引用它的 typescript 文件的顶部正确导入它。
像这样使用它。
const enum OperationsType{
CREATE="CREATE",
DELETE="DELETE",
UPDATE="UPDATE"
}
使用 //@ts-ignore
抑制你可以做:
//@ts-ignore
switch (EditMode[editMode] as EditMode) {
case EditMode.Delete:
...
break;
case EditMode.Edit:
...
break;
default:
...
break;
}
}