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

TypeScript中RTK Query如何配置全局/端点自定义错误类型

RTK Query 自定义接口错误类型配置方案

问题根源

你遇到的类型报错来自两个核心问题:

  • 直接对原生fetchBaseQuery做类型断言的写法无效:原生fetchBaseQuery的返回错误是固定的联合类型,包含网络错误、解析错误等客户端侧错误场景,硬断言为自定义类型会被TS检测到结构不匹配。
  • 自定义错误结构和实际返回结构不匹配:fetchBaseQuery返回的服务端业务错误,响应体统一挂载在error.data字段下,你之前定义的CustomError把message放在错误根层级,和实际结构不符。

方案1:全局统一配置所有接口的错误类型

第一步:定义覆盖全场景的错误类型

不要只定义业务错误结构,需要同时覆盖客户端侧请求异常(断网、超时、跨域等):

// 服务端返回的业务错误结构
type ApiBusinessError = {
  data: {
    message: string;
    // 可扩展其他业务错误字段,比如错误码、错误详情等
  };
  status: number;
};

// 客户端侧请求异常
type ApiRequestError = {
  status: "FETCH_ERROR";
  error: string;
};

// 全局统一错误类型
export type CustomError = ApiBusinessError | ApiRequestError;

第二步:包装基础请求方法,声明正确类型

不要直接断言原生fetchBaseQuery,加一层包装显式指定类型,还可以在这层加全局统一的错误处理逻辑(比如401自动跳登录、错误提示统一弹出等):

import { createApi, fetchBaseQuery, BaseQueryFn, FetchArgs } from '@reduxjs/toolkit/query/react';

const rawBaseQuery = fetchBaseQuery({
  baseUrl: "https://...",
  prepareHeaders: (headers) => {
    const token = localStorage.getItem("token");
    if (token) {
      headers.set("Authorization", `Bearer ${token}`);
    }
    return headers;
  },
});

// 显式声明包装后baseQuery的错误类型为自定义的CustomError
const baseQuery: BaseQueryFn<string | FetchArgs, unknown, CustomError, {}> = async (args, api, extraOptions) => {
  const result = await rawBaseQuery(args, api, extraOptions);
  // 可在这里加全局错误处理逻辑
  return result;
};

export const apiSlice = createApi({
  reducerPath: "api",
  baseQuery: baseQuery,
  endpoints: () => ({}),
});

使用时的类型安全调用

配置完成后,所有自动生成的query、mutation hook返回的error都会被推导为CustomError类型,只要做简单的类型收窄就能安全访问字段:

const [login, { error }] = useLoginMutation();

// 收窄为业务错误类型
if (error && "data" in error) {
  // TS会自动推导error为ApiBusinessError类型,可安全访问data.message
  alert(error.data.message);
}

// 收窄为网络错误类型
if (error && error.status === "FETCH_ERROR") {
  alert(`请求异常:${error.error}`);
}

方案2:给单个端点指定独立错误类型

如果部分接口的错误结构和全局结构不一致,可以在定义endpoint时单独指定错误类型,不需要修改全局配置:

// 登录接口独有的错误结构
type LoginApiError = {
  data: {
    message: string;
    code: number;
    remainAttempts?: number; // 剩余密码重试次数等独有字段
  };
  status: number;
};

export const authApi = apiSlice.injectEndpoints({
  endpoints: (builder) => ({
    // 第三个泛型参数传入自定义错误类型
    login: builder.mutation<LoginRes, LoginParams, { error: LoginApiError }>({
      query: (params) => ({
        url: "/auth/login",
        method: "POST",
        body: params,
      }),
    }),
  }),
});

配置后useLoginMutation返回的error会优先使用LoginApiError类型,不影响其他接口的全局类型。


内容的提问来源于stack exchange,提问作者Abhi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 11:45:31