在TypeScript中使用值字符串获取枚举键(反向映射)

时间:2019-01-21 20:31:48

标签: typescript

我有一个枚举:

export enum ApiMessages {
    logged_ok = 'Logged OK',
    register_ok = 'Register OK'
}

我有一个将枚举作为参数的函数:

export function responseOK(message: ApiMessages, result ?: any): ApiResponse {
    return {
        "status": "ok",
        "code": 200,
        "messageId": ApiMessages[message], <-- KO TS7015
        "message": message,
        "result": result
    };
}

我正在这样调用函数:

responseOK(ApiMessages.logged_ok, {user: userRes})

我试图将枚举键和枚举字符串值返回到响应中,但出现TS错误:

TS7015: Element implicitly has an 'any' type because index expression is not of type 'number'.

我有严格的TypeScript配置。不能添加excludeImplicitAnyIndexErrors。

TypeScript版本:2.9.2

5 个答案:

答案 0 :(得分:7)

handbook中所述:

  

请记住,字符串枚举成员根本不会生成反向映射。

这意味着您的情况没有简单的反向映射。

解决方法:为字符串枚举成员获取反向映射

要按其值获取枚举成员的键,您必须遍历枚举键,并将关联值与目标值进行比较。

function getEnumKeyByEnumValue(myEnum, enumValue) {
    let keys = Object.keys(myEnum).filter(x => myEnum[x] == enumValue);
    return keys.length > 0 ? keys[0] : null;
}

一些演示代码如下。您也可以see it in action on the TypeScript Playground

enum ApiMessages {
    logged_ok = 'Logged OK',
    register_ok = 'Register OK'
}    

let exampleValue = ApiMessages.logged_ok;
let exampleKey = getEnumKeyByEnumValue(ApiMessages, exampleValue);

alert(`The value '${exampleValue}' has the key '${exampleKey}'`)


function getEnumKeyByEnumValue(myEnum, enumValue) {
    let keys = Object.keys(ApiMessages).filter(x => myEnum[x] == enumValue);
    return keys.length > 0 ? keys[0] : null;
}

将此添加到您的responseOK()中,最终得到:

function responseOK(message: ApiMessages, result ?: any) {
    return {
        "status": "ok",
        "code": 200,
        "messageId": getEnumKeyByEnumValue(ApiMessages, message),
        "message": message,
        "result": result
    };
}

答案 1 :(得分:5)

您现在可以在 TypeScript 中获取类型中枚举的特征及其键??

 enum ApiMessage {
    logged_ok = 'Logged OK',
    register_ok = 'Register OK'
}

// "logged_ok" | "register_ok"
type ApiMessageTraits = keyof typeof ApiMessage;

// "Logged OK" | "Register OK"
type MessageContents = keyof { [M in keyof typeof ApiMessage as `${typeof ApiMessage[M]}`]: M };

遗憾的是,这依赖于将可枚举项的键转换为字符串,因此除了字符串之外,您不能拥有任何其他类型的键。

答案 2 :(得分:1)

对于那些像我一样看起来的人,这对我有用。

注意:仅当您知道您的字符串值是有效的“键”时,此选项才有效。

enum Fruit {
    Apple = 'apple',
    Bananna = 'bananna'
}

const str: string = 'apple';

const fruit = str as Fruit;

if (fruit === Fruit.Apple)
    console.log("It's an apple");

if (fruit === Fruit.Bananna)
    console.log("It's a bananna");

答案 3 :(得分:0)

您可以轻松创建一个映射,该映射允许您从值中获取键,而无需为其创建特殊功能。

export enum ApiMessage {
    logged_ok = 'Logged OK',
    register_ok = 'Register OK'
}

export type ApiMessageKey = keyof typeof ApiMessage;

export const API_MESSAGE_KEYS = new Map<ApiMessage, ApiMessageKey>(
    Object.entries(ApiMessage).map(([key, value]:[ApiMessageKey, ApiMessage]) => [value, key])
)

API_MESSAGE_KEYS.get(ApiMessage.logged_ok); // 'logged_ok'

答案 4 :(得分:0)

简体版本

枚举产生一个带有键-值对的对象。
您真正需要做的就是找到正确的条目(如果有)。

所以,举个例子

sbin.index = pd.to_datetime(sbin.index)
sbin = sbin.resample('W').agg({'High': 'max', 'Low': 'min', 'Close': 'last'})
print(sbin)

              High     Low   Close
Date                              
2020-10-18  205.95  191.60  195.95
2020-10-25  207.30  196.05  202.80

找到枚举条目

enum ApiMessages {
  Ok = 'OK',
  Forbidden = 'No access for you',
}

const example = ApiMessages.Forbidden;

选择密钥

const match = Object.entries(ApiMessages).find(([key, value]) => value === example);

就是这样。


在这里找到有效的example