如何按值查找枚举



我有一个enum,里面有一堆我翻译过的API消息,显示在前端:

export enum API_MESSAGES {
FAILED_TO_LOAD = 'Failed to load data',
TOKEN_INVALID = 'Token seems to be invalid',
}

我想使用来自后端的错误来获得翻译后的值:

onError: (error: AxiosError<ApiError>) => {
const errorRes = error.response?.data.error;
console.log(API_MESSAGES[errorRes])
}

然而,这会引发以下TS错误:

Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'typeof API_MESSAGES'
No index signature with a parameter of type 'string' was found on type 'typeof API_MESSAGES'

我尝试过搜索,但没有找到访问枚举的简单方法。

字符串枚举不支持反向映射

API_MESSAGES[errorRes]导致错误,因为根据打字手册:

反向映射

除了为成员创建具有属性名称的对象外,数字枚举成员还可以获得从枚举值到枚举名称的反向映射。

数字枚举是

编译为一个对象,该对象存储正向(名称->值(和反向(值->名称(映射。

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

,但您无论如何都不想要反向映射

您的目标是显示";翻译的";(人性化(API消息。因此,即使字符串枚举支持API_MESSAGES[errorRes],您也会这样做:

'Token seems to be invalid' --> TOKEN_INVALID 

即与你想要的相反。

如果您的后端使用相同的枚举定义,它将发送";翻译的";值已经存在

假设您的后端代码使用相同的API_MESSAGES枚举,那么实际上它所做的只是使用";一组命名常数";,例如FAILED_TO_LOADTOKEN_INVALID,其值是翻译的消息本身

换句话说,如果后端只是在其对前端的响应中串行化API_MESSAGES,那么它将发送";翻译的";消息已存在。

这意味着你的onError函数只是:

onError: (error: AxiosError<ApiError>) => {
const errorRes = error.response?.data.error;
console.log(errorRes)
}

从Typescript的角度以及您的逻辑意味着什么,error.response?.data.error的类型是API_MESSAGES。因为Typescript枚举实际上只是命名常量,这意味着error.response?.data.error实际上是以下联合类型

type API_MESSAGES = 'Failed to load data' | 'Token seems to be invalid',

因此,您将已经具有转换后的值。CCD_ 11和CCD_如果后端使用相同的枚举定义

如果您的后端正在发送代码,您只需要一个映射对象

如果FAILED_TO_LOADTOKEN_INVALID是后端发送的实际消息字符串,则只需要一个映射对象而不是枚举:

export const API_MESSAGES = {
FAILED_TO_LOAD = 'Failed to load data',
TOKEN_INVALID = 'Token seems to be invalid',
} as const;
// type API_MESSAGE = 'FAILED_TO_LOAD' | 'TOKEN_INVALID'
export type API_MESSAGE = keyof typeof API_MESSAGES

来自后端的错误代码是只是一个普通字符串,而不是类型化的Enum。此convertServerMessage函数演示如何验证它并将其转换为API_MESSAGE枚举。正如你之前所说,这是你所拥有的去某个地方做。您可能不需要这个单独的方法——相反,您可以将其逻辑放在代码中读取服务器响应并构造AxiosError对象的部分中,该对象的AxiosError.response.data.error应该具有API_MESSAGE类型。

export function convertServerMessage(msg: string): API_MESSAGE {
if (msg in API_MESSAGES) {
return msg as API_MESSAGE
} else {
// error logic goes here
}
}

那么您的原始onError将按照您的意愿工作(请参阅底部的注释(:

onError: (error: AxiosError<ApiError>) => {
// as I said above, the conversion from string code to 
// enum should probably happen elsewere. I have it here
// to keep the example simple.
const errorRes = convertServerMessage(error.response?.data.error);
console.log(API_MESSAGES[errorRes])
}

最新更新