[英]Getting the enum key with the value string (reverse mapping) in 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:元素隱式具有“任何”類型,因為索引表達式不是“數字”類型。
我有嚴格的 TypeScript 配置。 添加 suppressImplicitAnyIndexErrors 不是一個選項。
打字稿版本:2.9.2
如手冊中所述:
請記住,字符串枚舉成員根本不會生成反向映射。
這意味着在您的情況下沒有簡單的反向映射。
要通過值獲取枚舉成員的鍵,您必須遍歷枚舉鍵並將關聯的值與目標值進行比較。
function getEnumKeyByEnumValue(myEnum, enumValue) {
let keys = Object.keys(myEnum).filter(x => myEnum[x] == enumValue);
return keys.length > 0 ? keys[0] : null;
}
您可以更嚴格地按如下方式鍵入(請注意,我們可以將enum
解釋為可索引類型,此處的鍵和值都是字符串):
function getEnumKeyByEnumValue<T extends {[index:string]:string}>(myEnum:T, enumValue:string):keyof T|null {
let keys = Object.keys(myEnum).filter(x => myEnum[x] == enumValue);
return keys.length > 0 ? keys[0] : null;
}
下面是一些演示代碼。 您還可以在 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<T extends {[index:string]:string}>(myEnum:T, enumValue:string):keyof T|null {
let keys = Object.keys(myEnum).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
};
}
您可以輕松地創建一個映射,該映射允許您從值中獲取鍵,而無需為其創建特殊函數。
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'
對於那些看起來和我一樣的人來說,這對我有用。
注意:這僅在您知道您的字符串值是有效的“鍵”時才有效。
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");
您現在可以在 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 = `${ApiMessage}`;
可悲的是,這依賴於將可枚舉項的鍵轉換為字符串,因此除了字符串之外,您不能擁有任何其他類型的鍵。
編輯:通過使用帶有 TypeScript >=4.1
的模板文字大大簡化了第二種方法。
簡化版
枚舉生成一個帶有鍵值對的對象。
您真正需要做的就是找到正確的條目(如果有的話)。
所以,給定的例子
enum ApiMessages {
Ok = 'OK',
Forbidden = 'No access for you',
}
const example = ApiMessages.Forbidden;
找到枚舉條目
const match = Object.entries(ApiMessages).find(([key, value]) => value === example);
選擇鑰匙
if (match) {
const [key] = match;
console.log(`'${example}' matched key '${key}'.`);
}
// output: 'No access for you' matched key 'Forbidden'.
而已。
在這里找到一個工作示例。
您可以在此處使用lodash中的 .findKey 進行單行解決方案:
import { findKey } from 'lodash';
enum SomeType {
FOO = 'bar',
BAZ = 'qux'
}
const example = findKey(SomeType, (o) => o === 'bar');
console.log(example);
返回'FOO'
我從 API 收到了枚舉代碼,因此需要一種快速的方法來獲取描述......
在 js 中很容易做到,但在 Typescript 中卻不那么容易!
使用 Soren 的方法作為基礎
export function getEnumKeyByEnumValue<T extends { [index: string]: string }>(
myEnum: T,
enumValue: string
): keyof T | null {
let longDesc: string = 'No Match';
Object.keys(myEnum).forEach((key) => {
if (key == enumValue) longDesc = myEnum[key];
});
return longDesc;
}
getEnumKeyByEnumValue(BenefitType, appeal.benefit)
使用 lodash 你可以嘗試:
_.keys(ApiMessages)[_.toArray(ApiMessages).indexOf(ApiMessages.logged_ok)]
應該給你'logged_ok'
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.