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

如何在Redux Toolkit Query中用自定义injectGetItems生成可自动补全查询钩子?

解决方案

核心问题在于原实现中TypeScript无法捕获端点名称的具体字面量类型,也无法关联钩子与查询的参数/返回值类型。以下是修复后的完整实现:

关键修改点

  • 将端点名称设为泛型字面量类型,让TypeScript保留name参数的具体字符串值,而非宽泛的string类型
  • 精确定义返回类型,结合模板字符串类型与RTK Query内置类型,生成与端点匹配的钩子类型
  • 添加类型断言确保类型安全,在标签和返回对象上使用as const或类型断言,避免类型拓宽

修复后的代码

import { baseApi } from '../api';
import type { EndpointBuilder } from '@reduxjs/toolkit/query/react';

// 根据端点名称生成对应的useXxxQuery钩子类型
type InjectGetItemsReturn<T extends string, Response, Args> = {
  [K in `use${Capitalize<T>}Query`]: ReturnType<
    EndpointBuilder<any, any, any>['query']<Response, Args>
  >['useQuery'];
};

export const injectGetItems = <T extends string, ApiResponse, ApiArgs = void>(
  name: T,
  tag: string,
  url: string,
): InjectGetItemsReturn<T, ApiResponse, ApiArgs> => {
  const enhancedApi = baseApi.enhanceEndpoints({ addTagTypes: [tag] });

  const entityApi = enhancedApi.injectEndpoints({
    endpoints: (builder) => ({
      [name]: builder.query<ApiResponse, ApiArgs>({
        query: () => url,
        providesTags: (result) =>
          Array.isArray(result)
            ? [
                ...result.map((item) => ({ type: tag, id: item.id } as const)),
                { type: tag, id: 'LIST' } as const,
              ]
            : [{ type: tag, id: 'LIST' } as const],
      }),
    }),
    overrideExisting: false, // 防止意外覆盖已有端点
  });

  // 类型断言确保TypeScript识别钩子的名称与类型
  return {
    [`use${Capitalize(name)}Query`]: entityApi.endpoints[name].useQuery,
  } as InjectGetItemsReturn<T, ApiResponse, ApiArgs>;
};

细节说明

  • 泛型端点名称:T extends string让TypeScript记住传入的具体字符串(比如'getCharacter'),为生成useGetCharacterQuery提供类型依据
  • 返回类型关联:InjectGetItemsReturn通过模板字符串生成钩子名称,并直接关联RTK Query的query方法返回的useQuery类型,确保钩子的参数和返回值完全匹配ApiResponse和ApiArgs
  • as const断言:在providesTags中使用as const,让TypeScript识别标签的具体结构,避免被推断为宽泛的object类型,提升类型检查的准确性
  • overrideExisting配置:防止注入端点时意外覆盖已存在的端点,避免潜在的bug

验证用法

export const { useGetCharacterQuery } = injectGetItems<'getCharacter', CharacterResponse, void>(
  'getCharacter', 
  TAG_TYPES.rickAndMorty,
  QUERY_URL.rickandmorty_character
);

现在IDE会正确推断useGetCharacterQuery的类型,支持参数和返回值的自动补全。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 22:25:07