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

如何在RTK Query中编写类型正确的查询Hook包装函数

RTK Query 包装Hook类型报错修复

问题根因

  • data属性不存在的TS报错:自定义的selectFromResult类型定义打断了RTK Query原生的类型推导链,当传入自定义select配置时,TS会将hook返回值收窄为select函数的返回结构,当前泛型定义没有和原生hook的返回类型做关联,导致TS误判返回值仅包含refetch属性,无法识别data字段。
  • 类型无法收窄的问题:没有通过函数重载区分arg2是否传入的两种入参场景,TS无法根据入参形态推导对应的data类型,只能返回t1 | t1[]联合类型。

修复代码

// 保留原有自定义结果类型,补充refetch字段兼容原生返回
export type RTKQueryResult<T> = {
  data?: T;
  isLoading: boolean;
  isFetching: boolean;
  isSuccess: boolean;
  isError: boolean;
  refetch: () => void;
};

// 函数重载1:未传入arg2时,返回单条t1类型数据
export function useGetTQueryWrapper<RT = RTKQueryResult<t1>>(
  args: { arg1: string; arg2?: undefined },
  options?: {
    skip?: boolean;
    selectFromResult?: (result: RTKQueryResult<t1>) => RT;
  }
): RT;
// 函数重载2:传入arg2时,返回t1[]数组类型数据
export function useGetTQueryWrapper<RT = RTKQueryResult<t1[]>>(
  args: { arg1: string; arg2: string },
  options?: {
    skip?: boolean;
    selectFromResult?: (result: RTKQueryResult<t1[]>) => RT;
  }
): RT;
// 重载实现逻辑,内部类型不对外暴露
export function useGetTQueryWrapper<RT>(
  args: { arg1: string; arg2?: string },
  options: {
    skip?: boolean;
    selectFromResult?: (result: RTKQueryResult<t1 | t1[]>) => RT;
  } = {}
) {
  // 透传参数给原生hook,此处类型断言仅用于绕过内部类型校验,对外类型安全由重载保障
  const queryResult = useGetTQuery(args, options as any);

  if (!args.arg2) {
    return {
      ...queryResult,
      data: queryResult.data as t1
    } as RT;
  }

  return {
    ...queryResult,
    data: queryResult.data as t1[]
  } as RT;
}

使用说明

  • TS会自动根据传入的arg2参数匹配对应重载:传入arg2时,selectFromResult的入参result.data类型自动推导为t1[],未传入时自动推导为t1,最终返回的selectedData会自动收窄为对应类型,不会再出现联合类型问题。
  • 内部实现中options as any的写法是安全的,对外暴露的重载签名已经严格约束了入参和返回值的对应关系,不会产生类型漏洞。
  • 修复后解构原生hook返回值不会再报data不存在的错误,类型推导链会通过重载签名正确关联。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 09:51:17