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

如何为RTK Query/Mutation的EndpointDefinitions定义自定义参数类型?

RTK Query类型适配问题:添加路由参数、查询参数后触发TypeScript错误

原有可运行代码

export const reducerPath = 'api';
export const baseQuery = fetchBaseQuery({
  baseUrl: BASE_URL
});

export type QueryApiBuilderType = InjectedEndpointBuilder<typeof baseQuery, typeof reducerPath>;
export type InjectedEndpointBuilder<T extends BaseQueryFn, U extends string> = EndpointBuilder<T, never, U>;

export const createTransformedQueryEndpoint = <T, U = void>(build: QueryApiBuilderType, queryFetchArgs: FetchArgs) =>
  build.query<T, U>({
    query: () => queryFetchArgs,
    transformResponse: (response: { payload: T }) => response.payload
  });

export const createTransformedMutationEndpoint = <T, U>(build: QueryApiBuilderType, queryFetchArgs: FetchArgs) =>
  build.mutation<T, U>({
    query: (args) => ({
      body: args,
      ...queryFetchArgs
    }),
    transformResponse: (response: { payload: T }) => response.payload
  });

export interface IBaseItem {
  id: number;
  title: string;
}

export interface IItemResponse extends IBaseItem {
  fullText: string;
}

export const itemsApi = (build: QueryApiBuilderType, url = '/item') => ({
  getItems: createTransformedQueryEndpoint<IItemResponse[]>(build, { url }),
  createItem: createTransformedMutationEndpoint<IItemResponse, IBaseItemResponse>(build, { url, method: 'POST' })
});

const baseApi = createApi({
  reducerPath,
  baseQuery: fetchBaseQuery({
    baseUrl: BASE_URL
  }),
  endpoints: () => ({})
});

export const api = baseApi.injectEndpoints({
  endpoints: (build) => ({
    ...itemsApi(build)
  })
});

export const { useGetItemsQuery, useCreateItemMutation } = api;

修改后的代码(添加路由参数、查询参数后)

// modified createTransformedMutationEndpoint and createTransformedQueryEndpoint
 export const createTransformedQueryEndpoint = <T, U extends { id?: string | number; params?: object } = never>(
  build: QueryApiBuilderType,
  queryFetchArgs: FetchArgs
): EndpointDefinition<U, typeof baseQuery, string, T, typeof reducerPath> =>
  build.query<T, U>({
    query: ({ id, params, ...restQueryFetchArgs }) => ({
      url: `${queryFetchArgs.url}/${id}`,
      params,
      ...restQueryFetchArgs
    }),
    transformResponse: (response: { payload: T }) => response.payload
  });

export const createTransformedMutationEndpoint = <T, U extends { id?: string | number; params?: object } = never>(
  build: QueryApiBuilderType,
  queryFetchArgs: FetchArgs
): EndpointDefinition<U, typeof baseQuery, string, T, typeof reducerPath> =>
  build.mutation<T, U>({
    query: ({ id, params, ...restQueryFetchArgs }) => ({
      url: `${queryFetchArgs.url}/${id}`,
      params,
      body: restQueryFetchArgs,
      ...restQueryFetchArgs
    }),
    transformResponse: (response: { payload: T }) => response.payload
  });

export const itemsApi = (build: QueryApiBuilderType, url = '/item') => ({
  getItems: createTransformedQueryEndpoint<IItemResponse[]>(build, { url }),
  getItem: createTransformedQueryEndpoint<IItemResponse>(build, { url }), // added for id routeParam example
  createItem: createTransformedMutationEndpoint<IItemResponse, IBaseItem>(build, { url, method: 'POST' })
});

export const api = baseApi.injectEndpoints({
  endpoints: (build) => ({
    ...itemsApi(build) // ERROR 1
  })
});

export const { useGetItemsQuery, useGetItemQuery, useCreateItemMutation } = api; // ERROR 2

错误信息

ERROR 1

类型 { getItems: EndpointDefinition<never, BaseQueryFn<string | FetchArgs, unknown, FetchBaseQueryError, {}, FetchBaseQueryMeta>, string, IItemResponse[], "api">; getItem: EndpointDefinition<...>; createItem: EndpointDefinition<...>; } 无法分配给类型 EndpointDefinitions。
属性 getItems 与索引签名不兼容。
类型 EndpointDefinition<never, BaseQueryFn<string | FetchArgs, unknown, FetchBaseQueryError, {}, FetchBaseQueryMeta>, string, IItemResponse[], "api"> 无法分配给类型 EndpointDefinition<any, any, any, any, string>。
类型 EndpointDefinitionWithQuery<never, BaseQueryFn<string | FetchArgs, unknown, FetchBaseQueryError, {}, FetchBaseQueryMeta>, IItemResponse[]> & { ...; } & { ...; } & QueryExtraOptions<...> 无法分配给类型 EndpointDefinition<any, any, any, any, string>。
类型 EndpointDefinitionWithQuery<never, BaseQueryFn<string | FetchArgs, unknown, FetchBaseQueryError, {}, FetchBaseQueryMeta>, IItemResponse[]> & { ...; } & { ...; } & QueryExtraOptions<...> 无法分配给类型 EndpointDefinitionWithQuery<any, any, any> & { [resultType]?: any; [baseQuery]?: any; } & { extraOptions?: unknown; } & QueryExtraOptions<any, any, any, any, string>。
类型 EndpointDefinitionWithQuery<never, BaseQueryFn<string | FetchArgs, unknown, FetchBaseQueryError, {}, FetchBaseQueryMeta>, IItemResponse[]> & { ...; } & { ...; } & QueryExtraOptions<...> 无法分配给类型 QueryExtraOptions<any, any, any, any, string>。
属性 providesTags 的类型不兼容。
类型 ResultDescription<string, IItemResponse[], never, FetchBaseQueryError, FetchBaseQueryMeta | undefined> | undefined 无法分配给类型 ResultDescription<any, any, any, any, any> | undefined。
类型 GetResultDescriptionFn<string, IItemResponse[], never, FetchBaseQueryError, FetchBaseQueryMeta | undefined> 无法分配给类型 ResultDescription<any, any, any, any, any> | undefined。
类型 GetResultDescriptionFn<string, IItemResponse[], never, FetchBaseQueryError, FetchBaseQueryMeta | undefined> 无法分配给类型 GetResultDescriptionFn<any, any, any, any, any>。
类型 any 无法分配给类型 never。ts(2322)
apiTypes.d.ts(29, 20): 预期类型来自此签名的返回类型。

ERROR 2

类型 Api<BaseQueryFn<string | FetchArgs, unknown, FetchBaseQueryError, {}, FetchBaseQueryMeta>, EndpointDefinitions, "api", never, unique symbol | unique symbol> 上不存在属性 useGetItemQuery。
类型 Api<BaseQueryFn<string | FetchArgs, unknown, FetchBaseQueryError, {}, FetchBaseQueryMeta>, EndpointDefinitions, "api", never, unique symbol | unique symbol> 上不存在属性 useCreateItemMutation。
类型 Api<BaseQueryFn<string | FetchArgs, unknown, FetchBaseQueryError, {}, FetchBaseQueryMeta>, EndpointDefinitions, "api", never, unique symbol | unique symbol> 上不存在属性 useGetItemsQuery。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 16:35:04