Skip to content

Conversation

@DamianOsipiuk
Copy link
Contributor

@DamianOsipiuk DamianOsipiuk commented Nov 12, 2025

🎯 Changes

Fixes: #9789

βœ… Checklist

  • I have followed the steps in the Contributing guide.
  • I have tested this code locally with pnpm run test:pr.

πŸš€ Release Impact

  • This change affects published code, and I have generated a changeset.
  • This change is docs/CI/dev-only (no release).

Summary by CodeRabbit

  • New Features
    • useQuery now supports an options getter function, enabling dynamic option resolution. Options can be passed as a static object or as a reactive getter that returns the configuration, providing greater flexibility for reactive updates and computed query parameters.

@changeset-bot
Copy link

changeset-bot bot commented Nov 12, 2025

πŸ¦‹ Changeset detected

Latest commit: b2a96a9

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 2 packages
Name Type
@tanstack/vue-query Minor
@tanstack/vue-query-devtools Major

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 12, 2025

Walkthrough

This PR extends vue-query's useQuery hook to accept options as a getter function (MaybeRefOrGetter), enabling reactive lazy evaluation of query options. The implementation updates type signatures across useQuery and modifies useBaseQuery to resolve getter functions before processing, with a corresponding test validating the new behavior.

Changes

Cohort / File(s) Summary
Changeset documentation
.changeset/dark-birds-turn.md
Declares a minor version bump for @tanstack/vue-query and documents the new feat: support for options getter in useQuery
Type signature updates
packages/vue-query/src/useQuery.ts
Updated all useQuery overload signatures to wrap options parameter with MaybeRefOrGetter<UseQueryOptions<...>> instead of plain UseQueryOptions<...>, enabling getter/ref-based options
Options resolution logic
packages/vue-query/src/useBaseQuery.ts
Enhanced defaulted options computation to invoke options if it is a function, resolving the result before deep-cloning and further processing
Feature validation
packages/vue-query/src/__tests__/useQuery.test.ts
Added test case "should work with options getter" validating that useQuery correctly accepts a getter function returning an options object with queryKey and queryFn

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

  • Type signature updates are straightforward β€” wrapping options parameter consistently across overloads follows a clear pattern
  • Options resolution logic is focused β€” minimal conditional logic to handle getter functions, integrating cleanly with existing clone/mutation flow
  • Test validates the happy path β€” confirms end-to-end functionality without edge cases
  • Attention areas: Verify that getter resolution in useBaseQuery handles all reactive patterns correctly; confirm type overloads cover all documented use cases

Possibly related PRs

Suggested labels

package: vue-query

Poem

🐰 A getter hops into the query lane,
Lazy options no longer a strain,
Vue-query grows more spry,
With functions that fly,
Reactivity flows through the chain! 🌱

Pre-merge checks and finishing touches

❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Description check ⚠️ Warning PR description is incomplete. The Changes section lacks specific details about what was implemented and the motivation behind it. Add detailed description of changes in the Changes section: explain what the options getter feature does, how it works, and why it's needed. Reference the linked issue for context.
βœ… Passed checks (1 passed)
Check name Status Explanation
Title check βœ… Passed The title clearly and specifically describes the main feature being added: support for useQuery options getter in vue-query.
✨ Finishing touches
  • πŸ“ Generate docstrings
πŸ§ͺ Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch do/use-query-options-getter

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❀️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@nx-cloud
Copy link

nx-cloud bot commented Nov 12, 2025

View your CI Pipeline Execution β†— for commit b2a96a9

Command Status Duration Result
nx affected --targets=test:sherif,test:knip,tes... βœ… Succeeded 1m 38s View β†—
nx run-many --target=build --exclude=examples/*... βœ… Succeeded 19s View β†—

☁️ Nx Cloud last updated this comment at 2025-11-12 12:27:37 UTC

@pkg-pr-new
Copy link

pkg-pr-new bot commented Nov 12, 2025

More templates

@tanstack/angular-query-experimental

npm i https://pkg.pr.new/@tanstack/angular-query-experimental@9866

@tanstack/eslint-plugin-query

npm i https://pkg.pr.new/@tanstack/eslint-plugin-query@9866

@tanstack/query-async-storage-persister

npm i https://pkg.pr.new/@tanstack/query-async-storage-persister@9866

@tanstack/query-broadcast-client-experimental

npm i https://pkg.pr.new/@tanstack/query-broadcast-client-experimental@9866

@tanstack/query-core

npm i https://pkg.pr.new/@tanstack/query-core@9866

@tanstack/query-devtools

npm i https://pkg.pr.new/@tanstack/query-devtools@9866

@tanstack/query-persist-client-core

npm i https://pkg.pr.new/@tanstack/query-persist-client-core@9866

@tanstack/query-sync-storage-persister

npm i https://pkg.pr.new/@tanstack/query-sync-storage-persister@9866

@tanstack/react-query

npm i https://pkg.pr.new/@tanstack/react-query@9866

@tanstack/react-query-devtools

npm i https://pkg.pr.new/@tanstack/react-query-devtools@9866

@tanstack/react-query-next-experimental

npm i https://pkg.pr.new/@tanstack/react-query-next-experimental@9866

@tanstack/react-query-persist-client

npm i https://pkg.pr.new/@tanstack/react-query-persist-client@9866

@tanstack/solid-query

npm i https://pkg.pr.new/@tanstack/solid-query@9866

@tanstack/solid-query-devtools

npm i https://pkg.pr.new/@tanstack/solid-query-devtools@9866

@tanstack/solid-query-persist-client

npm i https://pkg.pr.new/@tanstack/solid-query-persist-client@9866

@tanstack/svelte-query

npm i https://pkg.pr.new/@tanstack/svelte-query@9866

@tanstack/svelte-query-devtools

npm i https://pkg.pr.new/@tanstack/svelte-query-devtools@9866

@tanstack/svelte-query-persist-client

npm i https://pkg.pr.new/@tanstack/svelte-query-persist-client@9866

@tanstack/vue-query

npm i https://pkg.pr.new/@tanstack/vue-query@9866

@tanstack/vue-query-devtools

npm i https://pkg.pr.new/@tanstack/vue-query-devtools@9866

commit: b2a96a9

@github-actions
Copy link
Contributor

Sizes for commit b2a96a9:

Branch Bundle Size
Main
This PR

@codecov
Copy link

codecov bot commented Nov 12, 2025

Codecov Report

βœ… All modified and coverable lines are covered by tests.
βœ… Project coverage is 71.28%. Comparing base (7783a7a) to head (b2a96a9).
⚠️ Report is 5 commits behind head on main.

Additional details and impacted files

Impacted file tree graph

@@             Coverage Diff             @@
##             main    #9866       +/-   ##
===========================================
+ Coverage   45.76%   71.28%   +25.51%     
===========================================
  Files         200       19      -181     
  Lines        8410      484     -7926     
  Branches     1930      140     -1790     
===========================================
- Hits         3849      345     -3504     
+ Misses       4113      109     -4004     
+ Partials      448       30      -418     
Components Coverage Ξ”
@tanstack/angular-query-experimental βˆ… <ΓΈ> (βˆ…)
@tanstack/eslint-plugin-query βˆ… <ΓΈ> (βˆ…)
@tanstack/query-async-storage-persister βˆ… <ΓΈ> (βˆ…)
@tanstack/query-broadcast-client-experimental βˆ… <ΓΈ> (βˆ…)
@tanstack/query-codemods βˆ… <ΓΈ> (βˆ…)
@tanstack/query-core βˆ… <ΓΈ> (βˆ…)
@tanstack/query-devtools βˆ… <ΓΈ> (βˆ…)
@tanstack/query-persist-client-core βˆ… <ΓΈ> (βˆ…)
@tanstack/query-sync-storage-persister βˆ… <ΓΈ> (βˆ…)
@tanstack/query-test-utils βˆ… <ΓΈ> (βˆ…)
@tanstack/react-query βˆ… <ΓΈ> (βˆ…)
@tanstack/react-query-devtools βˆ… <ΓΈ> (βˆ…)
@tanstack/react-query-next-experimental βˆ… <ΓΈ> (βˆ…)
@tanstack/react-query-persist-client βˆ… <ΓΈ> (βˆ…)
@tanstack/solid-query βˆ… <ΓΈ> (βˆ…)
@tanstack/solid-query-devtools βˆ… <ΓΈ> (βˆ…)
@tanstack/solid-query-persist-client βˆ… <ΓΈ> (βˆ…)
@tanstack/svelte-query βˆ… <ΓΈ> (βˆ…)
@tanstack/svelte-query-devtools βˆ… <ΓΈ> (βˆ…)
@tanstack/svelte-query-persist-client βˆ… <ΓΈ> (βˆ…)
@tanstack/vue-query 71.28% <100.00%> (+0.17%) ⬆️
@tanstack/vue-query-devtools βˆ… <ΓΈ> (βˆ…)
πŸš€ New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • πŸ“¦ JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (2)
packages/vue-query/src/__tests__/useQuery.test.ts (1)

47-63: LGTM! Test validates the basic getter usage.

The test correctly verifies that useQuery accepts a getter function returning options and produces the expected result state.

Consider adding a test case for a reactive getter to validate that changes to refs accessed inside the getter properly trigger re-computation:

test('should react to changes in options getter dependencies', async () => {
  const key = ref('initial-key')
  const query = useQuery(() => ({
    queryKey: ['reactive', key.value],
    queryFn: () => sleep(0).then(() => `result-${key.value}`),
  }))

  await vi.advanceTimersByTimeAsync(0)
  expect(query.data.value).toBe('result-initial-key')

  key.value = 'updated-key'
  await vi.advanceTimersByTimeAsync(0)
  expect(query.data.value).toBe('result-updated-key')
})

This would provide stronger validation of the reactivity behavior.

packages/vue-query/src/useQuery.ts (1)

91-109: Consider extending getter support to all overloads for type consistency.

The first two overloads (lines 97 and 107) accept DefinedInitialQueryOptions and UndefinedInitialQueryOptions directly, while the generic overloads (lines 117-119, 129-131) wrap UseQueryOptions in MaybeRefOrGetter.

This creates a type-level inconsistency: users can pass a getter returning options with initialData, and it will work at runtime (matching the generic overload), but they'll lose the refined return type (UseQueryDefinedReturnType) that guarantees data is defined.

Consider wrapping the first two overloads with MaybeRefOrGetter for consistency:

 export function useQuery<
   TQueryFnData = unknown,
   TError = DefaultError,
   TData = TQueryFnData,
   TQueryKey extends QueryKey = QueryKey,
 >(
-  options: DefinedInitialQueryOptions<TQueryFnData, TError, TData, TQueryKey>,
+  options: MaybeRefOrGetter<DefinedInitialQueryOptions<TQueryFnData, TError, TData, TQueryKey>>,
   queryClient?: QueryClient,
 ): UseQueryDefinedReturnType<TData, TError>

 export function useQuery<
   TQueryFnData = unknown,
   TError = DefaultError,
   TData = TQueryFnData,
   TQueryKey extends QueryKey = QueryKey,
 >(
-  options: UndefinedInitialQueryOptions<TQueryFnData, TError, TData, TQueryKey>,
+  options: MaybeRefOrGetter<UndefinedInitialQueryOptions<TQueryFnData, TError, TData, TQueryKey>>,
   queryClient?: QueryClient,
 ): UseQueryReturnType<TData, TError>

This would allow users to benefit from type refinement even when using getters.

πŸ“œ Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

πŸ“₯ Commits

Reviewing files that changed from the base of the PR and between f7c9526 and b2a96a9.

πŸ“’ Files selected for processing (4)
  • .changeset/dark-birds-turn.md (1 hunks)
  • packages/vue-query/src/__tests__/useQuery.test.ts (1 hunks)
  • packages/vue-query/src/useBaseQuery.ts (1 hunks)
  • packages/vue-query/src/useQuery.ts (2 hunks)
🧰 Additional context used
🧠 Learnings (1)
πŸ“š Learning: 2025-11-02T22:52:33.071Z
Learnt from: DogPawHat
Repo: TanStack/query PR: 9835
File: packages/query-core/src/__tests__/queryClient.test-d.tsx:242-256
Timestamp: 2025-11-02T22:52:33.071Z
Learning: In the TanStack Query codebase, the new `query` and `infiniteQuery` methods support the `select` option for data transformation, while the legacy `fetchQuery` and `fetchInfiniteQuery` methods do not support `select` and should reject it at the type level.

Applied to files:

  • .changeset/dark-birds-turn.md
🧬 Code graph analysis (3)
packages/vue-query/src/useBaseQuery.ts (2)
packages/query-core/src/queryObserver.ts (1)
  • options (379-385)
packages/vue-query/src/utils.ts (1)
  • cloneDeepUnref (70-97)
packages/vue-query/src/useQuery.ts (3)
packages/vue-query/src/types.ts (1)
  • MaybeRefOrGetter (27-27)
packages/react-query/src/types.ts (1)
  • UseQueryOptions (65-73)
packages/solid-query/src/types.ts (1)
  • UseQueryOptions (60-65)
packages/vue-query/src/__tests__/useQuery.test.ts (1)
packages/vue-query/src/useQuery.ts (1)
  • useQuery (123-137)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Preview
  • GitHub Check: Test
πŸ”‡ Additional comments (3)
.changeset/dark-birds-turn.md (1)

1-5: LGTM! Changeset is correctly formatted.

The minor version bump is appropriate for this new feature, and the description accurately summarizes the change.

packages/vue-query/src/useBaseQuery.ts (1)

84-89: LGTM! Getter resolution is correctly implemented.

The logic properly resolves the getter function before passing to cloneDeepUnref. Since this executes inside the computed(), any reactive dependencies accessed within the getter automatically become dependencies of the computed, ensuring proper reactivity.

packages/vue-query/src/useQuery.ts (1)

117-121: LGTM! Generic overloads correctly accept getters.

The type signatures properly reflect the new capability to accept options as MaybeRefOrGetter, enabling users to pass plain objects, refs, or getter functions.

Also applies to: 129-137

@DamianOsipiuk DamianOsipiuk merged commit b2bd79d into main Nov 12, 2025
9 checks passed
@DamianOsipiuk DamianOsipiuk deleted the do/use-query-options-getter branch November 12, 2025 12:35
@github-actions github-actions bot mentioned this pull request Nov 12, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Vue Query] queryOption type inference broken when using computed queryOption with select option

2 participants