求解: typescript 如何根据 enum 的字符值返回对应的 enum 实例?

351 天前
 hahaFck

比如定义以下 enum

const enum VerticalAlign {
   bottom, center, top
}

定义下面方法

//data 是后台返回的数据
function getVerticalAlign(data:JsonData):VerticalAlign {
	let value:string|null = data['vAlign'];
    switch(value) {
    	case VerticalAlign.bottom:
        	return VerticalAlign.bottom;
        ........
    }
}

现在的写法就是每个 enum 的值都要判断一次然后返回,有通用的方法返回一个 enum 的值么,直接写 VerticalAlign[value] 编译器报错.

1640 次点击
所在节点    程序员
23 条回复
hahaFck
351 天前
上面的例子写的简单,enum 实际是数字类型的,不是字符串类型。
t123yh
351 天前
let s = "bottom";

return VerticalAlign[s];
hahaFck
351 天前
@t123yh 不行啊,s 是后台返回来的值,这个时候不知道是哪个呢
devilte
351 天前
```
enum Position {
Top,
Right,
Bottom,
Left
}

const getPosition = (v: keyof typeof Position): Position=> {
return Position[v];
}

getPosition('Bottom');

```
是这个意思吧?
NoManPlay
351 天前
现在是要根据 value=0,返回对应的 bottom ,还是 value='bottom',获取对应的 0
hahaFck
351 天前
@devilte
@NoManPlay
我的意思是,后台返回来的值 s ,有可能是 enum 中的值的任意一个,想写一个通用的方法,根据值(string | number)来返回对应的 enum 类型。
NoManPlay
351 天前
```
enum VerticalAlign {
bottom,
center,
top,
}

function getVerticalAlign(value: any): VerticalAlign | null {
if (value in VerticalAlign) {
return VerticalAlign[value as keyof typeof VerticalAlign];
} else {
return null;
}
}
getVerticalAlign('bottom'); // 0
getVerticalAlign(''); // null
console.log(getVerticalAlign(0)); // bottom

```
debuggerx
351 天前
看看下面的比较结果:
console.info(VerticalAlign['bottom'] === VerticalAlign.bottom);
console.info(VerticalAlign['bottom1'] === VerticalAlign.bottom);

所以这种会后台传的,一般这样搞:
enum VerticalAlign {
bottom, center, top, unknown
}

let alignStr = "from server";

console.info(VerticalAlign[alignStr] ?? VerticalAlign.unknown);
hahaFck
351 天前
@NoManPlay
@debuggerx

好的,多谢二位哈哈,知道怎么搞了
hahaFck
351 天前
@debuggerx 不行啊,直接写 VerticalAlign[alignStr]报 No index signature with a parameter of type 'string' was found on type 'typeof VerticalAlign'.
paledream
351 天前
```typescript
enum VerticalAlign {
bottom = 1, center = 2, top = 3
}

type K = keyof typeof VerticalAlign

function getVerticalAlign(data:any): VerticalAlign {
let value: K = data['vAlign'];
return VerticalAlign[value]
}

```
walpurgis
351 天前
enum 是 ts 编译时的东西,js 里没有 enum ,运行时从外部获取的数据,ts 没法保证类型安全,所以 OP 想要的效果无论如何都绕不开 any 或类型断言,而 type safe 的方法就是一个个判断
mxT52CRuqR6o5
351 天前
难道不应该是直接
return value as any as VerticalAlign
吗,怎么一堆 return VerticalAlign[value]的
silk
351 天前
为什么 JsonData 定义的时候不知道,等使用的时候才去做类型判断
ysc3839
351 天前
@mxT52CRuqR6o5 楼主是要取 enum key string 对应的 value 吧?你这么转换类型结果还是 string
zbinlin
350 天前
mxT52CRuqR6o5
350 天前
@ysc3839 OP 给的代码每个 case return 一个 enum 的 value ,联合起来函数返回的应该是整个的 enum value ,没问题啊
假设现在有一个枚举
enum E {A,B}
type A = E.A|E.B 和 type B = E 应该是等价的
uni
350 天前
11 楼正解!
就是在定义 enum 的时候赋好值
enum VerticalAlign {
bottom = 1, center = 2, top = 3
}
ysc3839
350 天前
@mxT52CRuqR6o5 但是这明显不符合一般用途,一般是获取到了 enum key string ,要转换成 enum value ,前面几楼给的代码也是这个逻辑,楼主也没反对。具体是什么需求需要楼主出来解释清楚。
TWorldIsNButThis
350 天前
不要用 enum
这东西类型定义是坏的

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/940015

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX