Skip to content

feat: backport v5 apis to v4 #9140

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 1 commit into
base: v4
Choose a base branch
from

Conversation

manudeli
Copy link
Collaborator

@manudeli manudeli commented May 11, 2025

Initialized by #8754 with @danielpza

I added the v5 backport API to v4 based on the migration guide from migrating to v5 guide in TanStack Query Official Docs.

@tanstack/query-core

  1. add MutationObserverBaseResult.isPending
  2. tag keepPreviousData @deprecated
  3. tag jsdoc @deprecated on unnecessary function overloads of QueryClient's methods -- isFetching, ensureQueryData, getQueriesData, setQueriesData, removeQueries, resetQueries, cancelQueries, invalidateQueries, refetchQueries, fetchQuery, prefetchQuery, fetchInfiniteQuery, prefetchInfiniteQuery
  4. tag jsdoc @deprecated on unnecessary function overloads of QueryCache's methods -- find, findAll
    • add function overloads for QueryCache.find(filters)
  5. tag jsdoc @deprecated on unnecessary function overloads of useQuery, useInfiniteQuery

@tanstack/react-query

  1. add queryOptions
  2. add useSuspenseQuery
  3. add useSuspenseQueries

@tanstack/vue-query

  1. add function overloads for QueryCache.find(filters) like original QueryCache of @tanstack/query-core

I added test cases to guarantee all use cases with these apis backported

@manudeli manudeli changed the title feat(query-core, react-query): backport some v5 apis to v4 feat(query-core, react-query): backport v5 apis(useSuspenseQuery, useSuspenseQueries, queryOptions) to v4 May 11, 2025
Copy link

nx-cloud bot commented May 11, 2025

View your CI Pipeline Execution ↗ for commit b907fd5.

Command Status Duration Result
nx affected --targets=test:eslint,test:lib,test... ✅ Succeeded 1m 34s View ↗
nx affected --targets=test:lib --base=4e6432aed... ✅ Succeeded <1s View ↗

☁️ Nx Cloud last updated this comment at 2025-05-25 17:14:04 UTC

@manudeli manudeli changed the title feat(query-core, react-query): backport v5 apis(useSuspenseQuery, useSuspenseQueries, queryOptions) to v4 feat(query-core, react-query): backport v5 apis(isPending, useSuspenseQuery, useSuspenseQueries, queryOptions) to v4 May 11, 2025
Copy link

codesandbox-ci bot commented May 11, 2025

This pull request is automatically built and testable in CodeSandbox.

To see build info of the built libraries, click here or the icon next to each commit SHA.

Latest deployment of this branch, based on commit b907fd5:

Sandbox Source
@tanstack/query-example-react-basic-typescript Configuration
@tanstack/query-example-solid-basic-typescript Configuration
@tanstack/query-example-svelte-basic Configuration
@tanstack/query-example-vue-basic Configuration

@manudeli manudeli self-assigned this May 11, 2025
@manudeli manudeli force-pushed the backport-v5-apis-to-v4 branch 2 times, most recently from d9085f6 to 98805c8 Compare May 11, 2025 13:28
@manudeli manudeli marked this pull request as ready for review May 11, 2025 13:57
@manudeli manudeli requested a review from TkDodo May 11, 2025 13:58
Comment on lines 12 to 25
| 'getNextPageParam'
| 'getPreviousPageParam'
| 'queryKeyHashFn'
| '_defaulted'
| 'behavior'
| 'structuralSharing'
| 'isDataEqual'
| 'onSuccess'
| 'onError'
| 'onSettled'
| 'enabled'
| 'refetchInterval'
| 'initialData'
| 'networkMode'
Copy link
Collaborator

Choose a reason for hiding this comment

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

we don’t have this in v5. Where is this list coming from ?

Copy link
Collaborator Author

@manudeli manudeli May 12, 2025

Choose a reason for hiding this comment

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

You're right — only 'getNextPageParam', 'getPreviousPageParam', 'onSuccess', 'onError', 'onSettled', and 'context' needed to be omitted here since these properties are no longer present in v5. When I copied the Suspensive React Query code, I didn't reconsider whether this list was still relevant, and ended up including some obsolete entries. Thanks for catching that! I reflect in 6c9d86f

Also, I should have omitted 'refetchInterval' as well. If we don’t, it can cause a TypeScript error like below. I was a bit sad to leave it out 🥲 — but I figured it’s not a big deal to omit it from queryOptions for now, as we can remove
omitting 'refetchInterval' next time if need.

Without Omit refetchInterval

image

With Omit refetchInterval

image

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I'm going to explore some more to see if it's possible to support this without omitting refetchInterval. Will share back if I find a better workaround.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I explored a bit further to see if refetchInterval could be supported without breaking the v5 types, but unfortunately, I couldn’t find a viable workaround.

In v5, the refetchInterval function now receives only the Query object as its argument, whereas in v4 it used to receive both TData and Query. This change in signature makes it incompatible with v4-style callbacks. If we allow refetchInterval to pass through as-is, it could lead to subtle bugs or confusing TypeScript errors for users who are migrating and expect the old behavior.

Since the primary goal of queryOptions is to offer reusability and type safety across v5, I believe it’s better to leave refetchInterval out for now. Users who need it can still add it manually when configuring individual queries.

@manudeli manudeli force-pushed the backport-v5-apis-to-v4 branch from 3ea3785 to 6c9d86f Compare May 12, 2025 16:35
@manudeli manudeli marked this pull request as draft May 15, 2025 00:42
@manudeli manudeli force-pushed the backport-v5-apis-to-v4 branch from 6c9d86f to 56487e6 Compare May 18, 2025 17:30
Comment on lines +187 to +193
expectTypeOf(query2).toEqualTypeOf<
DefinedUseQueryResult<{ field: string }>
>()
expectTypeOf(query3).toEqualTypeOf<
DefinedUseQueryResult<{ field: string }>
>()
Copy link
Collaborator Author

@manudeli manudeli May 18, 2025

Choose a reason for hiding this comment

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

Fixed the issue where useQueries had to return DefinedUseQueryResult.
This was previously returning UseQueryResult instead of DefinedUseQueryResult.

@@ -256,6 +268,8 @@ export interface QueryObserverOptions<
/**
* Set this to `true` to keep the previous `data` when fetching based on a new query key.
* Defaults to `false`.
*
* @deprecated keepPreviousData will be removed in the next major version.
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Tagged @deprecated

@manudeli manudeli changed the title feat(query-core, react-query): backport v5 apis(isPending, useSuspenseQuery, useSuspenseQueries, queryOptions) to v4 feat(query-core, react-query): backport v5 apis to v4 May 21, 2025
@manudeli manudeli changed the title feat(query-core, react-query): backport v5 apis to v4 feat(query-core, react-query, vue-query): backport v5 apis to v4 May 21, 2025
Comment on lines +139 to +151
/**
* @deprecated This method will accept only queryKey in the next major version.
*/
getQueryData<TQueryFnData = unknown>(
queryKey: QueryKey,
filters: OmitKeyof<QueryFilters, 'queryKey'>,
): TQueryFnData | undefined
/**
* @deprecated This method will accept only queryKey in the next major version.
*/
getQueryData<TQueryFnData = unknown>(
queryKey: QueryKey,
filters?: OmitKeyof<QueryFilters, 'queryKey'>,
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

image

We can apply strikethrough to the unnecessary deprecated type overriding.

@manudeli manudeli force-pushed the backport-v5-apis-to-v4 branch 2 times, most recently from 3a518d9 to ab6151b Compare May 25, 2025 15:52
Comment on lines 168 to +170
find<TQueryFnData = unknown, TError = unknown, TData = TQueryFnData>(
arg1: QueryKey,
arg2?: QueryFilters,
filters: QueryFilters,
): Query<TQueryFnData, TError, TData> | undefined
Copy link
Collaborator Author

@manudeli manudeli May 25, 2025

Choose a reason for hiding this comment

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

I added a function overload accepting only a filters object. This could make migration to v5 easier. In v5, QueryCache.find only accepts a filters object

Comment on lines +171 to +183
/**
* @deprecated This method should be used with only one object argument.
*/
find<TQueryFnData = unknown, TError = unknown, TData = TQueryFnData>(
queryKey: QueryKey,
filters?: OmitKeyof<QueryFilters, 'queryKey'>,
): Query<TQueryFnData, TError, TData> | undefined
/**
* @deprecated This method should be used with only one object argument.
*/
find<TQueryFnData = unknown, TError = unknown, TData = TQueryFnData>(
arg1: QueryKey | QueryFilters,
arg2?: OmitKeyof<QueryFilters, 'queryKey'>,
Copy link
Collaborator Author

@manudeli manudeli May 25, 2025

Choose a reason for hiding this comment

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

I tagged jsdoc @deprecated on unnecessary type overriding of QueryCache's methods

Comment on lines +195 to +215
/**
* @deprecated This method should be used with only one object argument.
*/
findAll(
queryKey?: QueryKey,
filters?: OmitKeyof<QueryFilters, 'queryKey'>,
): Query[]
/**
* @deprecated This method should be used with only one object argument.
*/
findAll(
arg1?: QueryKey | QueryFilters,
arg2?: OmitKeyof<QueryFilters, 'queryKey'>,
): Query[]
/**
* @deprecated This method should be used with only one object argument.
*/
findAll(
arg1?: QueryKey | QueryFilters,
arg2?: OmitKeyof<QueryFilters, 'queryKey'>,
): Query[] {
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I tagged jsdoc @deprecated on unnecessary type overriding of QueryCache's methods

Comment on lines +152 to +153
isLoading,
isPending: isLoading,
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

We can use isPending like v5

Comment on lines +116 to 126
/**
* @deprecated This method should be used with only one object argument.
*/
isFetching(
queryKey?: QueryKey,
filters?: OmitKeyof<QueryFilters, 'queryKey'>,
): number
/**
* @deprecated This method should be used with only one object argument.
*/
isFetching(arg1?: QueryKey | QueryFilters, arg2?: QueryFilters): number {
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

tag jsdoc @deprecated on unnecessary function overloads

@manudeli manudeli force-pushed the backport-v5-apis-to-v4 branch 3 times, most recently from ab9aaf0 to d1698fa Compare May 25, 2025 17:05
@manudeli manudeli changed the title feat(query-core, react-query, vue-query): backport v5 apis to v4 feat: backport v5 apis to v4 May 25, 2025
Co-authored-by: Daniel Perez <[email protected]>
@manudeli manudeli force-pushed the backport-v5-apis-to-v4 branch from d1698fa to b907fd5 Compare May 25, 2025 17:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants