我有一个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_LOAD
和TOKEN_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_LOAD
和TOKEN_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])
}