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

Redux Toolkit调用updateQueryData报TS类型错误如何解决

Redux Toolkit Query 乐观更新类型报错ts(2345)修复

问题表现

实现RTK Query乐观更新时,调用api.util.updateQueryData传入端点名字符串'getPost',TS抛出类型错误:

Argument of type 'string' is not assignable to parameter of type 'never'.ts(2345)
对应问题代码:

const postsApiSlice = api.injectEndpoints({
  endpoints: (builder) => ({
    getPost: builder.query<Post, number>({
      query: (id) => ROUTES.POST(id),
      providesTags: (result, error, id) => {
        return [{ type: POST_TAG, id }]
      },
    }),
    updatePostWithOptimism: builder.mutation<void, Pick<Post, 'id'> & Partial<Post>>({
      query: ({ id, ...patch }) => ({
        url: ROUTES.POST(id),
        method: 'PATCH',
        body: patch,
      }),
      async onQueryStarted({ id, ...patch }, { dispatch, queryFulfilled }) {
        // 报错位置
        const manualGetPostUpdate = dispatch(api.util.updateQueryData('getPost', id, (draft) => {
          Object.assign(draft, patch)
        }))
        try {
          await queryFulfilled
        } catch {
          manualGetPostUpdate.undo()
        }
      },
    }),
  }),
})

报错原因

调用updateQueryData时使用的是未注入endpoints的原始api实例,TypeScript无法感知后续通过injectEndpoints动态注入的getPost端点,因此端点名称的联合类型被推导为never,不接受任何字符串参数传入。

修复方法

方案1(优先使用,零额外类型声明)

替换updateQueryData的调用主体,使用injectEndpoints返回的postsApiSlice上挂载的util方法,TS可以自动推导所有已注入端点的完整类型:

// 把原来的api.util替换为postsApiSlice.util
const manualGetPostUpdate = dispatch(postsApiSlice.util.updateQueryData('getPost', id, (draft) => {
  Object.assign(draft, patch)
}))

这种写法会自动做类型校验:如果端点名写错、传入的id类型不匹配、修改draft时字段类型错误,TS都会直接提示,不需要手动加任何类型定义。

方案2(适配必须使用原始api实例的场景)

如果受代码结构限制不能用注入后的slice实例,可以手动给updateQueryData传入泛型参数,明确指定端点的类型约束:

const manualGetPostUpdate = dispatch(
  api.util.updateQueryData<Post, number, 'getPost'>('getPost', id, (draft) => {
    Object.assign(draft, patch)
  })
)

三个泛型参数依次对应:

  • 对应query端点的返回值类型
  • 对应query端点接收的入参类型
  • 端点名称的字面量类型

常见避坑点

  • 不要让injectEndpoints的调用文件和api定义文件出现循环依赖,会直接导致TS类型推导失效
  • 代码分割场景下,要确保调用updateQueryData前,对应endpoint已经完成注入,否则运行时会找不到对应缓存条目
  • 不要给updateQueryData的第一个参数传变量,直接传字符串字面量才能让TS正确做类型校验

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 22:18:03