2017-07-03 251 views
6

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

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

,我需要像这样使用:

let modeStr: string; 
let mode: Mode = Mode[modeStr]; 

是的,我不知道它是什么有在modeStr串,我需要它解析如果该字符串未在枚举定义中出现,则返回枚举或在运行时解析失败。 我该怎么做,尽可能整洁? 在此先感谢

+1

可能的重复[在Typescript中使用字符串值创建枚举](https://stackoverflow.com/questions/15490560/create-an-enum-with-string-values-in-typescript) –

+0

@ ponury-kostek从技术上讲,这个问题并没有解决制作反向映射的问题。即使这样做,它可能会隐藏在底部的许多答案之一,使解决方案太难找到。我说如果没有更好的副本,让我们保留这一个。 –

回答

5

我们可以使Mode是一个类型和一个相同类型的值。

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 

字符串枚举为this answer

enum Mode { 
    Silent = <any>"Silent", 
    Normal = <any>"Normal", 
    Deleted = <any>"Deleted" 
} 

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

mode = Mode[modeStr]; // Silent 
mode = Mode.Normal; // Normal 
//mode = "Deleted"; // Error 
mode = Mode["unknown"]; // undefined 
+0

谢谢......它可能已经在打字稿中实现了。 –

+0

tslint会在该Enum示例中抛出一个错误:*元素隐含地具有'any'类型,因为索引表达式不是'number'*类型。我想问题是,在TS字符串中枚举不能反向映射,请参阅String-Enum示例中的注释,位于https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-4 .html - 对于引入String-Enum的TS 2.4来说,这似乎是正确的,但我也在TS 2.6.2中得到错误 – masi

+0

@masi从2.4开始,TS支持字符串枚举,所以您不需要添加''演员。 – Rodris

1

如果你确定使用代理服务器,我做了一个比较通用的&紧凑型:

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>; 
} 

用法:

import stringEnum from './stringEnum'; 
type Mode = "Silent" | "Normal" | "Deleted"; 
const Mode = stringEnum<Mode>(); 
0

我发现迄今最彻底的方法是使二次地图:

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

因此,你可以做let mode: Mode = reverseMode.get('Silent');

优点:不需要重复这些值,提供枚举枚举的方法,让TSLint保持高兴......

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