如何优雅处理Axios与TypeScript中try-catch返回类型不匹配问题
Axios + TypeScript 异步函数类型不匹配问题的优雅解决
你的问题核心是函数声明的返回类型和catch块的返回值类型完全不兼容:你定义函数返回Promise<GetProductsResponse>,但catch分支返回的是number | undefined,TypeScript会严格校验Promise的resolve值类型,这种矛盾必然导致类型错误。以下是几种实用的处理方案:
方案1:抛出自定义错误(推荐,符合异步编程惯例)
异步函数的错误逻辑应该通过throw抛出,而非返回错误值。这样函数的返回类型能保持Promise<GetProductsResponse>,错误流由调用方的catch处理,同时可以自定义错误类携带状态码等信息:
// 自定义错误类,封装请求错误详情 class ApiRequestError extends Error { status?: number; constructor(message: string, status?: number) { super(message); this.name = 'ApiRequestError'; this.status = status; } } export async function getProducts(): Promise<GetProductsResponse> { try { const response = await productsClient.get<ApiResponse<GetProductsResponse>>('/get-product'); return response.data.body.data; } catch (error) { const axiosError = error as AxiosError; // 抛出包含状态码的自定义错误 throw new ApiRequestError(axiosError.message, axiosError.response?.status); } } // 调用方示例 getProducts() .then(products => console.log('获取产品:', products)) .catch((err: ApiRequestError) => { console.error(`请求失败:状态码${err.status},原因${err.message}`); });
这种方式遵循JS/TS异步编程的错误处理惯例,数据流和错误流分离,逻辑更清晰。
方案2:统一返回类型(适合同步处理成功/失败场景)
如果业务需要函数返回一个包含成功/失败状态的统一结果,可以定义联合类型来包裹两种情况:
// 定义统一返回类型,明确区分成功/失败状态 type ApiResult<T> = | { success: true; data: T } | { success: false; status?: number; error: string }; export async function getProducts(): Promise<ApiResult<GetProductsResponse>> { try { const response = await productsClient.get<ApiResponse<GetProductsResponse>>('/get-product'); return { success: true, data: response.data.body.data }; } catch (error) { const axiosError = error as AxiosError; return { success: false, status: axiosError.response?.status, error: axiosError.message }; } } // 调用方示例 const result = await getProducts(); if (result.success) { console.log('产品列表:', result.data); } else { console.error(`请求失败:状态码${result.status},${result.error}`); }
这种方式不需要调用方使用try/catch,直接通过success字段判断结果状态,适合需要同步处理成功/失败逻辑的场景。
方案3:直接抛出原始AxiosError(快速实现)
如果不需要额外封装错误,直接抛出AxiosError即可,上层调用方可以直接访问Axios错误的所有属性:
import { AxiosError } from 'axios'; export async function getProducts(): Promise<GetProductsResponse> { try { const response = await productsClient.get<ApiResponse<GetProductsResponse>>('/get-product'); return response.data.body.data; } catch (error) { // 直接抛出AxiosError,交由调用方处理 throw error as AxiosError; } } // 调用方示例 try { const products = await getProducts(); console.log('产品列表:', products); } catch (err) { const axiosError = err as AxiosError; console.error(`请求失败:状态码${axiosError.response?.status},${axiosError.message}`); }
这种方式代码最少,适合快速实现或上层需要直接处理Axios原生错误的场景。
内容的提问来源于stack exchange,提问作者Pentium3k
相关产品推荐
相关产品推荐

