You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何优雅处理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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 10:45:27