Axios+TypeScript场景下Promise reject错误为unknown类型的解决咨询
解决方案
你遇到的是TypeScript下try/catch块错误默认是unknown类型的典型场景,结合Axios的特性有两种成熟的处理方案:
方案1:基于Axios原生错误类型做类型收窄
Axios 已经内置了AxiosError泛型类型,同时自带类型守卫方法axios.isAxiosError(),可以直接用来收窄错误类型,不需要修改后端现有接口规范:
步骤1:复用你已定义的错误响应结构
export interface ErrorRes { statusCode: number; error: string; message: string; } export interface ISignupRes { token: string; user: IUser; message: string; }
步骤2:修改catch块逻辑,增加类型判断
import type { AxiosError } from 'axios' const handleSignUp = async () => { setLoading(true) try { const { data, status } = await coreApi.post<ISignupRes>('/auth/signup', { email, username, firstname, lastname, password, }) // 非2xx状态码会直接进入catch,这里不需要额外判断status Storage.save(true, 'token', data.token) addNotification({ type: 'success', message: data.message, }) setLoading(false) } catch (error) { setLoading(false) let errMsg = '注册失败,请稍后重试' // 用Axios自带的类型守卫收窄错误类型 if (coreApi.isAxiosError<ErrorRes>(error)) { // 优先取服务端返回的错误信息 errMsg = error.response?.data?.message ?? errMsg } addNotification({ type: 'error', message: errMsg, }) } }
注:你原有代码中的else分支永远不会执行,因为Axios默认会将所有非2xx/3xx的响应判定为异常,直接进入catch块,可以直接删除该分支。
方案2:统一200状态码封装响应结构
如果你们还在对齐接口规范,这种方案业务层开发效率更高:所有接口都返回200状态码,响应体统一封装code、msg、data三个字段,仅网络异常、跨域等底层问题才会进入catch块。
步骤1:定义通用响应结构
// 通用响应泛型,T为业务数据类型 export interface CommonRes<T = null> { code: number; // 成功为0/200,失败为自定义错误码 msg: string; // 成功提示/错误信息 data: T; // 业务数据,失败时为null } // 业务类型保持不变 export interface ISignupRes { token: string; user: IUser; message: string; }
步骤2:业务代码无需处理异常分支
const handleSignUp = async () => { setLoading(true) try { const { data } = await coreApi.post<CommonRes<ISignupRes>>('/auth/signup', { email, username, firstname, lastname, password, }) if (data.code === 200) { Storage.save(true, 'token', data.data.token) addNotification({ type: 'success', message: data.msg, }) } else { addNotification({ type: 'error', message: data.msg, }) } } catch (error) { addNotification({ type: 'error', message: '网络异常,请稍后重试' }) } finally { setLoading(false) } }
方案选择建议
- 如果后端已经遵循Restful规范,用HTTP状态码区分错误类型,选方案1即可,无需改造现有接口
- 如果接口规范还在迭代,优先选方案2,业务层不需要处理大量HTTP错误分支,类型定义更统一,维护成本更低
内容的提问来源于stack exchange,提问作者JonasLevin
相关产品推荐
相关产品推荐

