Skip to content

Commit 5b39d68

Browse files
committed
feat(react-query): backport v5 apis about infinite query
1 parent 1f9cf0b commit 5b39d68

File tree

8 files changed

+287
-12
lines changed

8 files changed

+287
-12
lines changed
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { infiniteQueryOptions } from '../infiniteQueryOptions'
2+
3+
describe('infiniteQueryOptions', () => {
4+
it('should return the object received as a parameter without any modification.', () => {
5+
const object = {
6+
queryKey: ['key'],
7+
queryFn: () => Promise.resolve(5),
8+
getNextPageParam: () => null,
9+
} as const
10+
11+
expect(infiniteQueryOptions(object)).toStrictEqual(object)
12+
})
13+
})
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
import { expectTypeOf } from 'expect-type'
2+
import {
3+
type InfiniteData,
4+
type UseInfiniteQueryResult,
5+
useInfiniteQuery,
6+
useQueryClient,
7+
} from '@tanstack/react-query'
8+
9+
import {
10+
type UseSuspenseInfiniteQueryResult,
11+
useSuspenseInfiniteQuery,
12+
} from '../useSuspenseInfiniteQuery'
13+
import { infiniteQueryOptions } from '../infiniteQueryOptions'
14+
15+
const infiniteQuery = {
16+
options1: () =>
17+
infiniteQueryOptions({
18+
queryKey: ['key', 1] as const,
19+
queryFn: () => Promise.resolve({ field: 'success' }),
20+
}),
21+
options2: () =>
22+
infiniteQueryOptions({
23+
queryKey: ['key', 2] as const,
24+
queryFn: () => Promise.resolve({ field: 'success' }),
25+
initialData: () => ({ pageParams: [], pages: [{ field: 'success' }] }),
26+
}),
27+
}
28+
29+
const Ex = () => {
30+
useInfiniteQuery({
31+
queryKey: ['key', 2] as const,
32+
queryFn: () => Promise.resolve({ field: 'success' }),
33+
initialData: () => ({ pageParams: [], pages: [{ field: 'success' }] }),
34+
})
35+
}
36+
37+
describe('infiniteQueryOptions', () => {
38+
it('should be used with useInfiniteQuery', () => {
39+
const keyFn1Query = useInfiniteQuery(infiniteQuery.options1())
40+
expectTypeOf(keyFn1Query).toEqualTypeOf<
41+
UseInfiniteQueryResult<{ field: string }>
42+
>()
43+
expectTypeOf(keyFn1Query.data).toEqualTypeOf<
44+
InfiniteData<{ field: string }> | undefined
45+
>()
46+
const keyFn1Query_Select = useInfiniteQuery({
47+
...infiniteQuery.options1(),
48+
select: (data) => ({
49+
pages: data.pages.map(({ field }) => field),
50+
pageParams: data.pageParams,
51+
}),
52+
})
53+
expectTypeOf(keyFn1Query_Select).toEqualTypeOf<
54+
UseInfiniteQueryResult<string>
55+
>()
56+
expectTypeOf(keyFn1Query_Select.data).toEqualTypeOf<
57+
InfiniteData<string> | undefined
58+
>()
59+
})
60+
it('should be used with useSuspenseInfiniteQuery', () => {
61+
const dd = infiniteQuery.options1()
62+
const keyFn1SuspenseQuery = useSuspenseInfiniteQuery(
63+
infiniteQuery.options1(),
64+
)
65+
expectTypeOf(keyFn1SuspenseQuery).toEqualTypeOf<
66+
UseSuspenseInfiniteQueryResult<{ field: string }>
67+
>()
68+
expectTypeOf(keyFn1SuspenseQuery.data).toEqualTypeOf<
69+
InfiniteData<{ field: string }>
70+
>()
71+
const keyFn1SuspenseQuery_Select = useSuspenseInfiniteQuery({
72+
...infiniteQuery.options1(),
73+
select: (data) => ({
74+
pages: data.pages.map(({ field }) => field),
75+
pageParams: data.pageParams,
76+
}),
77+
})
78+
expectTypeOf(keyFn1SuspenseQuery_Select).toEqualTypeOf<
79+
UseSuspenseInfiniteQueryResult<string>
80+
>()
81+
expectTypeOf(keyFn1SuspenseQuery_Select.data).toEqualTypeOf<
82+
InfiniteData<string>
83+
>()
84+
})
85+
it('should be used with useQueryClient', async () => {
86+
const queryClient = useQueryClient()
87+
88+
queryClient.invalidateQueries(infiniteQuery.options1())
89+
queryClient.resetQueries(infiniteQuery.options1())
90+
queryClient.removeQueries(infiniteQuery.options1())
91+
queryClient.cancelQueries(infiniteQuery.options1())
92+
queryClient.prefetchQuery(infiniteQuery.options1())
93+
queryClient.refetchQueries(infiniteQuery.options1())
94+
95+
const query1 = await queryClient.fetchQuery(infiniteQuery.options1())
96+
expectTypeOf(query1).toEqualTypeOf<InfiniteData<{ field: string }>>()
97+
})
98+
})

packages/react-query/src/index.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ export { useQueries } from './useQueries'
1212
export type { QueriesResults, QueriesOptions } from './useQueries'
1313
export { useQuery } from './useQuery'
1414
export { useSuspenseQuery } from './useSuspenseQuery'
15+
export { useSuspenseInfiniteQuery } from './useSuspenseInfiniteQuery'
1516
export { useSuspenseQueries } from './useSuspenseQueries'
1617
export type {
1718
SuspenseQueriesResults,
@@ -22,6 +23,11 @@ export type {
2223
DefinedInitialDataOptions,
2324
UndefinedInitialDataOptions,
2425
} from './queryOptions'
26+
export { infiniteQueryOptions } from './infiniteQueryOptions'
27+
export type {
28+
DefinedInitialDataInfiniteOptions,
29+
UndefinedInitialDataInfiniteOptions,
30+
} from './infiniteQueryOptions'
2531
export {
2632
defaultContext,
2733
QueryClientProvider,
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
import type { UseInfiniteQueryOptions } from './types'
2+
import type {
3+
InfiniteData,
4+
NonUndefinedGuard,
5+
OmitKeyof,
6+
QueryKey,
7+
WithRequired,
8+
} from '@tanstack/query-core'
9+
10+
type UseInfiniteQueryOptionsOmitted<
11+
TQueryFnData = unknown,
12+
TError = unknown,
13+
TData = TQueryFnData,
14+
TQueryKey extends QueryKey = QueryKey,
15+
> = OmitKeyof<
16+
UseInfiniteQueryOptions<TQueryFnData, TError, TData, TQueryFnData, TQueryKey>,
17+
'onSuccess' | 'onError' | 'onSettled' | 'refetchInterval'
18+
>
19+
20+
type ProhibitedInfiniteQueryOptionsKeyInV5 = keyof Pick<
21+
UseInfiniteQueryOptionsOmitted,
22+
'useErrorBoundary' | 'suspense'
23+
>
24+
25+
export type UndefinedInitialDataInfiniteOptions<
26+
TQueryFnData,
27+
TError = unknown,
28+
TData = TQueryFnData,
29+
TQueryKey extends QueryKey = QueryKey,
30+
> = UseInfiniteQueryOptionsOmitted<TQueryFnData, TError, TData, TQueryKey> & {
31+
initialData?: undefined
32+
}
33+
34+
export type DefinedInitialDataInfiniteOptions<
35+
TQueryFnData,
36+
TError = unknown,
37+
TData = TQueryFnData,
38+
TQueryKey extends QueryKey = QueryKey,
39+
> = UseInfiniteQueryOptionsOmitted<TQueryFnData, TError, TData, TQueryKey> & {
40+
initialData:
41+
| NonUndefinedGuard<InfiniteData<TData>>
42+
| (() => NonUndefinedGuard<InfiniteData<TData>>)
43+
| undefined
44+
}
45+
46+
export function infiniteQueryOptions<
47+
TQueryFnData,
48+
TError = unknown,
49+
TData = TQueryFnData,
50+
TQueryKey extends QueryKey = QueryKey,
51+
>(
52+
options: WithRequired<
53+
OmitKeyof<
54+
DefinedInitialDataInfiniteOptions<TQueryFnData, TError, TData, TQueryKey>,
55+
ProhibitedInfiniteQueryOptionsKeyInV5
56+
>,
57+
'queryKey'
58+
>,
59+
): WithRequired<
60+
DefinedInitialDataInfiniteOptions<TQueryFnData, TError, TData, TQueryKey>,
61+
'queryKey'
62+
>
63+
64+
export function infiniteQueryOptions<
65+
TQueryFnData,
66+
TError = unknown,
67+
TData = TQueryFnData,
68+
TQueryKey extends QueryKey = QueryKey,
69+
>(
70+
options: WithRequired<
71+
OmitKeyof<
72+
UndefinedInitialDataInfiniteOptions<
73+
TQueryFnData,
74+
TError,
75+
TData,
76+
TQueryKey
77+
>,
78+
ProhibitedInfiniteQueryOptionsKeyInV5
79+
>,
80+
'queryKey'
81+
>,
82+
): WithRequired<
83+
UndefinedInitialDataInfiniteOptions<TQueryFnData, TError, TData, TQueryKey>,
84+
'queryKey'
85+
>
86+
87+
export function infiniteQueryOptions(options: unknown) {
88+
return options
89+
}

packages/react-query/src/queryOptions.ts

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,15 @@ export type UndefinedInitialDataOptions<
2727
TError = unknown,
2828
TData = TQueryFnData,
2929
TQueryKey extends QueryKey = QueryKey,
30-
> = UseQueryOptionsOmitted<TQueryFnData, TError, TData, TQueryKey> & {
31-
initialData?:
32-
| undefined
33-
| InitialDataFunction<NonUndefinedGuard<TQueryFnData>>
34-
| NonUndefinedGuard<TQueryFnData>
35-
}
30+
> = WithRequired<
31+
UseQueryOptionsOmitted<TQueryFnData, TError, TData, TQueryKey> & {
32+
initialData?:
33+
| undefined
34+
| InitialDataFunction<NonUndefinedGuard<TQueryFnData>>
35+
| NonUndefinedGuard<TQueryFnData>
36+
},
37+
'queryKey'
38+
>
3639

3740
export type DefinedInitialDataOptions<
3841
TQueryFnData = unknown,

packages/react-query/src/useInfiniteQuery.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@ export function useInfiniteQuery<
2424
TQueryKey
2525
>,
2626
): UseInfiniteQueryResult<TData, TError>
27+
/**
28+
* @deprecated This function overload will be removed in the next major version.
29+
*/
2730
export function useInfiniteQuery<
2831
TQueryFnData = unknown,
2932
TError = unknown,
@@ -42,6 +45,9 @@ export function useInfiniteQuery<
4245
'queryKey'
4346
>,
4447
): UseInfiniteQueryResult<TData, TError>
48+
/**
49+
* @deprecated This function overload will be removed in the next major version.
50+
*/
4551
export function useInfiniteQuery<
4652
TQueryFnData = unknown,
4753
TError = unknown,

packages/react-query/src/useQuery.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ export function useQuery<
5555
options: UseQueryOptions<TQueryFnData, TError, TData, TQueryKey>,
5656
): UseQueryResult<TData, TError>
5757

58-
/** @deprecated */
58+
/** @deprecated This function overload will be removed in the next major version. */
5959
export function useQuery<
6060
TQueryFnData = unknown,
6161
TError = unknown,
@@ -68,7 +68,7 @@ export function useQuery<
6868
'queryKey' | 'initialData'
6969
>,
7070
): UseQueryResult<TData, TError>
71-
/** @deprecated */
71+
/** @deprecated This function overload will be removed in the next major version. */
7272
export function useQuery<
7373
TQueryFnData = unknown,
7474
TError = unknown,
@@ -81,7 +81,7 @@ export function useQuery<
8181
'queryKey' | 'initialData'
8282
> & { initialData: TQueryFnData | (() => TQueryFnData) },
8383
): DefinedUseQueryResult<TData, TError>
84-
/** @deprecated */
84+
/** @deprecated This function overload will be removed in the next major version. */
8585
export function useQuery<
8686
TQueryFnData = unknown,
8787
TError = unknown,
@@ -94,7 +94,7 @@ export function useQuery<
9494
'queryKey'
9595
>,
9696
): UseQueryResult<TData, TError>
97-
/** @deprecated */
97+
/** @deprecated This function overload will be removed in the next major version. */
9898
export function useQuery<
9999
TQueryFnData = unknown,
100100
TError = unknown,
@@ -108,7 +108,7 @@ export function useQuery<
108108
'queryKey' | 'queryFn' | 'initialData'
109109
> & { initialData?: () => undefined },
110110
): UseQueryResult<TData, TError>
111-
/** @deprecated */
111+
/** @deprecated This function overload will be removed in the next major version. */
112112
export function useQuery<
113113
TQueryFnData = unknown,
114114
TError = unknown,
@@ -122,7 +122,7 @@ export function useQuery<
122122
'queryKey' | 'queryFn' | 'initialData'
123123
> & { initialData: TQueryFnData | (() => TQueryFnData) },
124124
): DefinedUseQueryResult<TData, TError>
125-
/** @deprecated */
125+
/** @deprecated This function overload will be removed in the next major version. */
126126
export function useQuery<
127127
TQueryFnData = unknown,
128128
TError = unknown,
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import { useInfiniteQuery } from './useInfiniteQuery'
2+
import type { WithRequired } from './../../query-core/src/types'
3+
import type { InfiniteData, OmitKeyof, QueryKey } from '@tanstack/query-core'
4+
import type { UseInfiniteQueryOptions, UseInfiniteQueryResult } from './types'
5+
6+
export interface UseSuspenseInfiniteQueryResult<
7+
TData = unknown,
8+
TError = unknown,
9+
> extends OmitKeyof<
10+
UseInfiniteQueryResult<TData, TError>,
11+
keyof Pick<UseInfiniteQueryResult<TData, TError>, 'isPlaceholderData'>
12+
> {
13+
data: InfiniteData<TData>
14+
}
15+
16+
export type UseSuspenseInfiniteQueryOptions<
17+
TQueryFnData = unknown,
18+
TError = unknown,
19+
TData = TQueryFnData,
20+
TQueryKey extends QueryKey = QueryKey,
21+
> = WithRequired<
22+
OmitKeyof<
23+
UseInfiniteQueryOptions<
24+
TQueryFnData,
25+
TError,
26+
TData,
27+
TQueryFnData,
28+
TQueryKey
29+
>,
30+
| 'suspense'
31+
| 'useErrorBoundary'
32+
| 'enabled'
33+
| 'placeholderData'
34+
| 'networkMode'
35+
| 'initialData'
36+
>,
37+
'queryKey'
38+
>
39+
40+
export function useSuspenseInfiniteQuery<
41+
TQueryFnData = unknown,
42+
TError = unknown,
43+
TData = TQueryFnData,
44+
TQueryKey extends QueryKey = QueryKey,
45+
>(
46+
options: UseSuspenseInfiniteQueryOptions<
47+
TQueryFnData,
48+
TError,
49+
TData,
50+
TQueryKey
51+
>,
52+
): UseSuspenseInfiniteQueryResult<TData, TError> {
53+
return useInfiniteQuery({
54+
...options,
55+
enabled: true,
56+
suspense: true,
57+
useErrorBoundary: true,
58+
networkMode: 'always',
59+
}) as UseSuspenseInfiniteQueryResult<TData, TError>
60+
}

0 commit comments

Comments
 (0)