Javascript 字符串枚举的反向映射

Javascript 字符串枚举的反向映射,javascript,node.js,typescript,visual-studio-code,msdn,Javascript,Node.js,Typescript,Visual Studio Code,Msdn,我想在typescript中使用字符串枚举,但我看不到它对反向映射的支持。 我有这样一个枚举: enum Mode { Silent = "Silent", Normal = "Normal", Deleted = "Deleted" } let modeStr: string; let mode: Mode = Mode[modeStr]; 我需要这样使用它: enum Mode { Silent = "Silent", Normal = "Norm

我想在typescript中使用字符串枚举,但我看不到它对反向映射的支持。 我有这样一个枚举:

enum Mode {
    Silent = "Silent",
    Normal = "Normal",
    Deleted = "Deleted"
}
let modeStr: string;
let mode: Mode = Mode[modeStr];
我需要这样使用它:

enum Mode {
    Silent = "Silent",
    Normal = "Normal",
    Deleted = "Deleted"
}
let modeStr: string;
let mode: Mode = Mode[modeStr];
是的,我不知道它在
modeStr
字符串中是什么,我需要将它解析到枚举中,或者在运行时解析失败,如果该字符串没有出现在枚举定义中。 我怎样才能做到尽可能整洁呢?
提前感谢

我们可以使
模式
成为同一类型的类型和值

type Mode = string;
let Mode = {
    Silent: "Silent",
    Normal: "Normal",
    Deleted: "Deleted"
}

let modeStr: string = "Silent";
let mode: Mode;

mode = Mode[modeStr]; // Silent
mode = Mode.Normal; // Normal
mode = "Deleted"; // Deleted
mode = Mode["unknown"]; // undefined
mode = "invalid"; // "invalid"
更严格的版本:

type Mode = "Silent" | "Normal" | "Deleted";
const Mode = {
    get Silent(): Mode { return "Silent"; },
    get Normal(): Mode { return "Normal"; },
    get Deleted(): Mode { return "Deleted"; }
}

let modeStr: string = "Silent";
let mode: Mode;

mode = Mode[modeStr]; // Silent
mode = Mode.Normal; // Normal
mode = "Deleted"; // Deleted
mode = Mode["unknown"]; // undefined
//mode = "invalid"; // Error
字符串枚举为:

enum模式{
Silent=“Silent”,
Normal=“Normal”,
Deleted=“已删除”
}
让modeStr:string=“沉默”;
让模式:模式;
模式=模式[modeStr];//沉默的
模式=模式。正常;//正常的
//mode=“已删除”//错误
模式=模式[“未知”];//未定义

如果您不介意使用代理,我制作了一个更通用、更紧凑的版本:

type Mode = "Silent" | "Normal" | "Deleted";
const Mode = {
    get Silent(): Mode { return "Silent"; },
    get Normal(): Mode { return "Normal"; },
    get Deleted(): Mode { return "Deleted"; }
}

let modeStr: string = "Silent";
let mode: Mode;

mode = Mode[modeStr]; // Silent
mode = Mode.Normal; // Normal
mode = "Deleted"; // Deleted
mode = Mode["unknown"]; // undefined
//mode = "invalid"; // Error
stringEnum.ts

export type StringEnum<T extends string> = {[K in T]: K}
const proxy = new Proxy({}, {
  get(target, property) {
    return property;
  }
})
export default function stringEnum<T extends string>(): StringEnum<T> {
  return proxy as StringEnum<T>;
}
导出类型StringEnum={[K in T]:K}
const proxy=新代理({}{
获取(目标、属性){
归还财产;
}
})
导出默认函数stringEnum():stringEnum{
将代理返回为StringEnum;
}
用法:

import stringEnum from './stringEnum';
type Mode = "Silent" | "Normal" | "Deleted";
const Mode = stringEnum<Mode>();
从“/stringEnum”导入stringEnum;
键入Mode=“Silent”|“Normal”|“Deleted”;
常量模式=stringEnum();

到目前为止,我找到的最干净的方法是制作二级映射:

let reverseMode = new Map<string, Mode>();
Object.keys(Mode).forEach((mode: Mode) => {
    const modeValue: string = Mode[<any>mode];
    reverseMode.set(modeValue, mode);
});
let reverseMode=new Map();
Object.keys(Mode).forEach((Mode:Mode)=>{
常量modeValue:string=Mode[Mode];
反向模式设置(模式值,模式);
});
因此,您可以执行以下操作:
let mode:mode=reverseMode.get('Silent')

优点:无需重复这些值,提供枚举枚举的方法,使TSLint保持愉快


编辑:我最初写的是
Mode[Mode]
,但是TS可能会在这一行抛出错误TS7015,所以我添加了演员阵容。

没有一个答案对我有效,所以我不得不回到正常的循环。 我的枚举是

enum SOME_CONST{
      STRING1='value1', 
      STRING2 ='value2',
      .....and so on
}


getKeyFromValue =(value:string)=> Object.entries(SOME_CONST).filter((item)=>item[1]===value)[0][0];

这个答案来自@PhiLho

我没有足够的代表对他的消息发表评论

let reverseMode = new Map<string, Mode>();
Object.keys(Mode).forEach((mode: Mode) => {
    const modeValue: string = Mode[<any>mode];
    reverseMode.set(modeValue, mode);
});

@PhiLho可能没有看到这一点的原因是,OP提供的原始对象的键和值是相同的。

对于所有仍在努力解决这一问题的人来说,这是一种快速而肮脏的方法

enum Mode {
    Silent = "Silent",
    Normal = "Normal",
    Deleted = "Deleted"
}

const currMode = 'Silent',
  modeKey = Object.keys(Mode)[(Object.values(Mode) as string[]).indexOf(currMode)];
然而,有一些警告,你应该知道

Microsoft将Git bug标记为“按预期工作”的最可能原因可能是,它处理的是字符串文本,而as枚举最初设计为可索引的。虽然上面的代码可以使用TSLint并使用lint,但它有两个问题。对象在转换为数组时不能保证保持预期的顺序,我们处理的字符串文字可能是唯一的,也可能不是唯一的

看看这个StackBlitz,其中有两种模式的值为“静默”。您不能保证在查找完成后,它不会返回“忽略”而不是“静默”


从技术上讲,@ponury kostek的可能重复,该问题不涉及制作反向映射的问题。即使是这样,它也可能隐藏在隐藏在底部的众多答案中的一个,使得解决方案很难找到。我说,如果没有更好的副本,我们就保留这个副本。谢谢……它本可以在typescript中实现。tslint将在该枚举上抛出一个错误示例:元素隐式地具有“any”类型,因为索引表达式不是“number”类型。我想问题在于TS中的字符串枚举无法反向映射,请参见位于的字符串枚举示例中的注释-对于引入字符串枚举的TS 2.4,这似乎是正确的,但我在TS 2.6中也遇到了错误。2@masi从2.4开始,TS支持字符串枚举,所以你不需要添加
演员阵容。@RodrigoPedrosa我知道。该错误在有或无)的情况下都会发生,但它被关闭为“按预期工作”。似乎TS开发人员从未使用过任何其他支持字符串求值的语言,否则他们不会声称它按预期工作。充其量,它对一个试图将类型带到另一个语言的语言来说“尽可能好”(到目前为止,我还没有检查技术原因)。@masi我不确定你在说什么。反向映射在操场上工作。您的问题是否与tslint有关?