如果你看MyEnum
在运行时,它本质上是一个像这样的对象:
{ YES: 'x', NO: 'y' }
JavaScript 中没有自动反向查找对象,因此您需要编写类似的内容find()
函数来做到这一点。所以我认为没有什么更简单的了,没有。
如果你的枚举是numeric,TypeScript 会给你那些自动反向映射:
enum MyEnum {
YES = 1,
NO = 0
}
const oneKey = MyEnum[1]; // "YES" (typed as string)
const zeroKey = MyEnum[0]; // "NO" (typed as string)
但可惜的是,您使用的是字符串枚举,因此这里没有神奇的答案。
If你经常需要进行反向查找并且不想继续迭代数组来完成它,你可以使用如下的辅助函数提前构建一个反向映射对象:
type ReverseMapping<T extends Record<keyof T, keyof any>> = {
[K in T[keyof T]]: { [P in keyof T]: K extends T[P] ? P : never }[keyof T]
}
function reverseMapping<T extends Record<keyof T, keyof any>>(t: T): ReverseMapping<T> {
const ret = {} as ReverseMapping<T>;
(Object.keys(t) as Array<keyof T>).forEach(k => ret[t[k]] = k as any);
return ret;
}
然后像这样使用它:
// do this once
const reverseMyEnum = reverseMapping(MyEnum); // reverseMyEnum: { x: "YES", y: "NO" }
// reuse reverseMyEnum for reverse lookups:
const xKey = reverseMyEnum.x; // xKey: "YES"
const yKey = reverseMyEnum.y; // yKey: "NO"
const randKey = reverseMyEnum[Math.random() < 0.5 ? "x" : "y"]; // randKey: "YES" | "NO"
当然,reverseMapping()
功能可能比“过度设计”find()
,所以这对你来说是否值得取决于你。我倾向于继续使用find()
(虽然类型更强,但并不是您要求的)除非我遇到了某种问题(例如,不断迭代一个真正巨大的枚举的性能......不太可能)。
无论如何希望有帮助。祝你好运!