[vue-query] useQuery rejects spreading a queryOptions() result + override since v5.98.0
维护者通常 1 天内回复
还没有人认领这个 Issue。
评估
- 难度
- 4/5
- 预计耗时
- 3-5 天
- 新手友好度
- 55/100
- Issue 类型
- 缺陷
- 描述清晰度
- 描述清楚
- 活跃度
- 冷清
- 技术栈
- typescript
- 领域
- frontend
调研方向
从 queryOptions 和 useQuery 入口开始进行最小复现,针对 5.97.0 和 5.98.0+ 版本运行 tsc --noEmit 或 vue-tsc。跟踪 spread 形式所涉及的 queryKey branding 和选项推断;当文档中的 spread-and-override 示例能够在没有 TS2769 的情况下通过类型检查,同时直接使用 useQuery(opts) 仍然有效时,即视为完成。
由索引模型根据 Issue 内容生成。
描述
Describe the bug
Since @tanstack/vue-query v5.98.0, the documented pattern of spreading a queryOptions(...) result into useQuery and overriding a non-data-shaping option (e.g. enabled) no longer type-checks. Passing the same options object directly works; only the spread + override form fails.
This is a downstream continuation of #10525. That fix made queryOptions({ queryKey: computed(...) }) type-check again, but the branded queryKey (DataTag<...>) is still inconsistent with the other option properties once the result is spread into a fresh object literal, so useQuery inference fails with TS2769: No overload matches this call.
The most revealing part of the error cascade:
Types of property 'staleTime' are incompatible.
...
Type 'readonly ["activity", "detail", string | null | undefined]' is not assignable to type
'{ ...; [dataTagErrorSymbol]: Error; }'.
Your minimal, reproducible example
import { queryOptions, useQuery } from "@tanstack/vue-query"
import { computed, type MaybeRefOrGetter, toValue } from "vue"
const fooQueryOptions = (id: MaybeRefOrGetter<string | null>) =>
queryOptions({
queryKey: computed(() => ["foo", toValue(id)] as const),
queryFn: async () => {
const v = toValue(id)
return v ? { id: v } : null
},
})
// ✅ OK — passed directly
useQuery(fooQueryOptions("1"))
// ❌ TS2769 since 5.98.0 (works on 5.97.0) — spread + override
useQuery({
...fooQueryOptions("1"),
enabled: () => true,
})
Steps to reproduce
- Install
@tanstack/[email protected](or any version from 5.98.0 onward). - Define a
queryOptions(...)factory with acomputedqueryKey. - Spread its result into
useQuery({ ...opts, enabled: () => true }). - Run
tsc --noEmit/vue-tsc. - TypeScript reports
TS2769: No overload matches this call, bottoming out at thequeryKeymissing thedataTagSymbol/dataTagErrorSymbolbrand.
Note: useQuery(opts) (passing the same options directly, without spreading or overriding) type-checks fine — only the spread + override form fails.
Expected behavior
Spreading a queryOptions(...) result and overriding enabled (or other non-data-shaping options) should type-check, as shown in the docs and as it did on 5.97.0:
https://tanstack.com/query/latest/docs/framework/vue/guides/query-options
How often does this bug happen?
Every time
Screenshots or videos
No response
Platform
- TanStack Query version: broken on 5.98.0 – 5.101.0; last working 5.97.0
- TypeScript version: 5.8+
- Vue version: 3.5+
Additional context
Same class of regression as #10458 (fixed enabled) and #10525 (fixed queryKey on queryOptions), but it surfaces at the useQuery call site when spreading a queryOptions(...) result and overriding a property. Pinning to 5.97.0 produces zero type errors; any of 5.98.0 – 5.101.0 reproduces it.
- 主要语言
- TypeScript
- 星标
- 50.4k
- 派生
- 4.2k
- 平均合并
- 7 小时 37 分钟
- 30 天内合并 PR
- 420
环境准备
- 没有 Dockerfile 或 Docker Compose 文件
- 有 Pull Request 模板
- 阅读贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
TanStack/query 的其他 Issue
-
QueryClient.isFetching and useIsFetching accept a fetchStatus filter and ignore it可能已有人在做 @Apu-Emdad 今天认领。 未关闭
难度 2/5 1-3 小时 新手友好度 78/100
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 72/100
TanStack/query#11930 · 1 条评论 ·
维护者通常 1 天内回复
-
solid-query: STRICT_READ_UNTRACKED on Solid 2 — client()/options() read in component body (useMutation, useBaseQuery)可能重新可做 @LeonxLJX 于 39 天前认领,目前没有进行中的 PR。 未关闭
难度 2/5 1-3 小时 新手友好度 84/100
TanStack/query#11358 · 2 条评论 · 1 个 reaction ·
维护者通常 1 天内回复
-
solid-query: switching the queryClient accessor strands the new client's cache (subscription stays on the old observer)可能已有人在做 @MaNaN1803 于 82 天前认领。 未关闭
难度 2/5 1-3 小时 新手友好度 84/100
TanStack/query#11106 · 1 条评论 ·
维护者通常 1 天内回复
-
restoreQueries and persisterGc throw on malformed persisted entries可能已有人在做 @VGontier-cmd 于 7 天前认领。 未关闭
难度 3/5 1-2 天 新手友好度 72/100
维护者通常 1 天内回复
相似的 Issue
-
难度 2/5 1-3 小时 新手友好度 70/100
NaturalIntelligence/fast-xml-parser#890 · 1 条评论 ·
维护者通常 3 天内回复
-
难度 2/5 1-3 小时 新手友好度 62/100
zsviczian/obsidian-excalidraw-plugin#3000 ·
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 68/100
pnpm/get.pnpm.io#68 ·
-
[BUG] Cloudflare KV binding 模式下 kvDriver.list() 沿用 EdgeOne 语义,字段名不匹配导致 key 格式下初始化 500 并耗尽 list 配额可能已有人在做 @wumingzhinu 今天认领。 未关闭bug
难度 2/5 1-3 小时 新手友好度 64/100
OpenListTeam/OpenList-Worker#125 ·
维护者通常 2 天内回复
-
Android (vision-camera-location): HybridLocationManager never quits its HandlerThread on dispose未关闭
难度 2/5 1-3 小时 新手友好度 74/100
margelo/react-native-vision-camera#4217 ·
维护者通常 4 天内回复