Skip to content

Commit 91dd479

Browse files
authored
feat: add PageParam typing (#5005)
* feat: add PageParam typing * feat(infinite-query): more typing * feat(infinite-query): make pageParam never by defaukt * feat(infinite-query): PageParam type unknown for infinite queries * fix(infinite-query): fix tests * feat(infinite-query): add previous end next return TPageParam type
1 parent 268813a commit 91dd479

File tree

9 files changed

+174
-296
lines changed

9 files changed

+174
-296
lines changed

packages/query-core/src/infiniteQueryBehavior.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import type {
44
InfiniteData,
55
InfiniteQueryOptions,
66
QueryFunctionContext,
7+
QueryKey,
78
} from './types'
89

910
export function infiniteQueryBehavior<
@@ -74,15 +75,20 @@ export function infiniteQueryBehavior<
7475
return Promise.resolve(pages)
7576
}
7677

77-
const queryFnContext: Omit<QueryFunctionContext, 'signal'> = {
78+
const queryFnContext: Omit<
79+
QueryFunctionContext<QueryKey, unknown>,
80+
'signal'
81+
> = {
7882
queryKey: context.queryKey,
7983
pageParam: param,
8084
meta: context.options.meta,
8185
}
8286

8387
addSignalProperty(queryFnContext)
8488

85-
const queryFnResult = queryFn(queryFnContext as QueryFunctionContext)
89+
const queryFnResult = queryFn(
90+
queryFnContext as QueryFunctionContext<QueryKey, unknown>,
91+
)
8692

8793
const promise = Promise.resolve(queryFnResult).then((page) =>
8894
buildNewPages(pages, param, page, previous),

packages/query-core/src/query.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -362,7 +362,6 @@ export class Query<
362362
// Create query function context
363363
const queryFnContext: Omit<QueryFunctionContext<TQueryKey>, 'signal'> = {
364364
queryKey: this.queryKey,
365-
pageParam: undefined,
366365
meta: this.meta,
367366
}
368367

packages/query-core/src/queryClient.ts

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -275,8 +275,15 @@ export class QueryClient {
275275
TError = RegisteredError,
276276
TData = TQueryFnData,
277277
TQueryKey extends QueryKey = QueryKey,
278+
TPageParam = never,
278279
>(
279-
options: FetchQueryOptions<TQueryFnData, TError, TData, TQueryKey>,
280+
options: FetchQueryOptions<
281+
TQueryFnData,
282+
TError,
283+
TData,
284+
TQueryKey,
285+
TPageParam
286+
>,
280287
): Promise<TData> {
281288
const defaultedOptions = this.defaultQueryOptions(options)
282289

@@ -308,8 +315,15 @@ export class QueryClient {
308315
TError = RegisteredError,
309316
TData = TQueryFnData,
310317
TQueryKey extends QueryKey = QueryKey,
318+
TPageParam = unknown,
311319
>(
312-
options: FetchInfiniteQueryOptions<TQueryFnData, TError, TData, TQueryKey>,
320+
options: FetchInfiniteQueryOptions<
321+
TQueryFnData,
322+
TError,
323+
TData,
324+
TQueryKey,
325+
TPageParam
326+
>,
313327
): Promise<InfiniteData<TData>> {
314328
options.behavior = infiniteQueryBehavior<TQueryFnData, TError, TData>()
315329
return this.fetchQuery(options)
@@ -320,8 +334,15 @@ export class QueryClient {
320334
TError = RegisteredError,
321335
TData = TQueryFnData,
322336
TQueryKey extends QueryKey = QueryKey,
337+
TPageParam = unknown,
323338
>(
324-
options: FetchInfiniteQueryOptions<TQueryFnData, TError, TData, TQueryKey>,
339+
options: FetchInfiniteQueryOptions<
340+
TQueryFnData,
341+
TError,
342+
TData,
343+
TQueryKey,
344+
TPageParam
345+
>,
325346
): Promise<void> {
326347
return this.fetchInfiniteQuery(options).then(noop).catch(noop)
327348
}
@@ -405,9 +426,17 @@ export class QueryClient {
405426
TData = TQueryFnData,
406427
TQueryData = TQueryFnData,
407428
TQueryKey extends QueryKey = QueryKey,
429+
TPageParam = never,
408430
>(
409431
options?:
410-
| QueryObserverOptions<TQueryFnData, TError, TData, TQueryData, TQueryKey>
432+
| QueryObserverOptions<
433+
TQueryFnData,
434+
TError,
435+
TData,
436+
TQueryData,
437+
TQueryKey,
438+
TPageParam
439+
>
411440
| DefaultedQueryObserverOptions<
412441
TQueryFnData,
413442
TError,

packages/query-core/src/tests/query.test.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,7 @@ describe('query', () => {
200200
expect(queryFn).toHaveBeenCalledTimes(1)
201201
const args = queryFn.mock.calls[0]![0]
202202
expect(args).toBeDefined()
203+
// @ts-expect-error page param should be undefined
203204
expect(args.pageParam).toBeUndefined()
204205
expect(args.queryKey).toEqual(key)
205206
expect(args.signal).toBeInstanceOf(AbortSignal)

packages/query-core/src/tests/queryClient.test.tsx

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -565,15 +565,16 @@ describe('queryClient', () => {
565565
pageParams: [0],
566566
} as const
567567

568-
const fetchFn: QueryFunction<StrictData, StrictQueryKey> = () =>
568+
const fetchFn: QueryFunction<StrictData, StrictQueryKey, number> = () =>
569569
Promise.resolve(data.pages[0])
570570

571571
await expect(
572572
queryClient.fetchInfiniteQuery<
573573
StrictData,
574574
any,
575575
StrictData,
576-
StrictQueryKey
576+
StrictQueryKey,
577+
number
577578
>({ queryKey: key, queryFn: fetchFn, defaultPageParam: 0 }),
578579
).resolves.toEqual(data)
579580
})
@@ -603,14 +604,15 @@ describe('queryClient', () => {
603604
type StrictQueryKey = ['strict', ...ReturnType<typeof queryKey>]
604605
const key: StrictQueryKey = ['strict', ...queryKey()]
605606

606-
const fetchFn: QueryFunction<StrictData, StrictQueryKey> = () =>
607+
const fetchFn: QueryFunction<StrictData, StrictQueryKey, number> = () =>
607608
Promise.resolve('data')
608609

609610
await queryClient.prefetchInfiniteQuery<
610611
StrictData,
611612
any,
612613
StrictData,
613-
StrictQueryKey
614+
StrictQueryKey,
615+
number
614616
>({ queryKey: key, queryFn: fetchFn, defaultPageParam: 0 })
615617

616618
const result = queryClient.getQueryData(key)

packages/query-core/src/types.ts

Lines changed: 48 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -22,17 +22,24 @@ export type QueryKey = readonly unknown[]
2222
export type QueryFunction<
2323
T = unknown,
2424
TQueryKey extends QueryKey = QueryKey,
25-
> = (context: QueryFunctionContext<TQueryKey>) => T | Promise<T>
25+
TPageParam = never,
26+
> = (context: QueryFunctionContext<TQueryKey, TPageParam>) => T | Promise<T>
2627

27-
export interface QueryFunctionContext<
28+
export type QueryFunctionContext<
2829
TQueryKey extends QueryKey = QueryKey,
29-
TPageParam = any,
30-
> {
31-
queryKey: TQueryKey
32-
signal: AbortSignal
33-
pageParam?: TPageParam
34-
meta: QueryMeta | undefined
35-
}
30+
TPageParam = never,
31+
> = [TPageParam] extends [never]
32+
? {
33+
queryKey: TQueryKey
34+
signal: AbortSignal
35+
meta: QueryMeta | undefined
36+
}
37+
: {
38+
queryKey: TQueryKey
39+
signal: AbortSignal
40+
pageParam: TPageParam
41+
meta: QueryMeta | undefined
42+
}
3643

3744
export type InitialDataFunction<T> = () => T | undefined
3845

@@ -50,15 +57,15 @@ export type QueryKeyHashFunction<TQueryKey extends QueryKey> = (
5057
queryKey: TQueryKey,
5158
) => string
5259

53-
export type GetPreviousPageParamFunction<TQueryFnData = unknown> = (
60+
export type GetPreviousPageParamFunction<TPageParam, TQueryFnData = unknown> = (
5461
firstPage: TQueryFnData,
5562
allPages: TQueryFnData[],
56-
) => unknown
63+
) => TPageParam | undefined
5764

58-
export type GetNextPageParamFunction<TQueryFnData = unknown> = (
65+
export type GetNextPageParamFunction<TPageParam, TQueryFnData = unknown> = (
5966
lastPage: TQueryFnData,
6067
allPages: TQueryFnData[],
61-
) => unknown
68+
) => TPageParam | undefined
6269

6370
export interface InfiniteData<TData> {
6471
pages: TData[]
@@ -76,6 +83,7 @@ export interface QueryOptions<
7683
TError = RegisteredError,
7784
TData = TQueryFnData,
7885
TQueryKey extends QueryKey = QueryKey,
86+
TPageParam = never,
7987
> {
8088
/**
8189
* If `false`, failed queries will not retry by default.
@@ -87,7 +95,7 @@ export interface QueryOptions<
8795
retryDelay?: RetryDelayValue<TError>
8896
networkMode?: NetworkMode
8997
gcTime?: number
90-
queryFn?: QueryFunction<TQueryFnData, TQueryKey>
98+
queryFn?: QueryFunction<TQueryFnData, TQueryKey, TPageParam>
9199
queryHash?: string
92100
queryKey?: TQueryKey
93101
queryKeyHashFn?: QueryKeyHashFunction<TQueryKey>
@@ -114,22 +122,24 @@ export interface QueryOptions<
114122
maxPages?: number
115123
}
116124

117-
export interface DefaultPageParam {
118-
defaultPageParam: unknown
125+
export interface DefaultPageParam<TPageParam = unknown> {
126+
defaultPageParam: TPageParam
119127
}
120128

121-
export interface InfiniteQueryOptions<TQueryFnData = unknown>
122-
extends DefaultPageParam {
129+
export interface InfiniteQueryOptions<
130+
TQueryFnData = unknown,
131+
TPageParam = unknown,
132+
> extends DefaultPageParam<TPageParam> {
123133
/**
124134
* This function can be set to automatically get the previous cursor for infinite queries.
125135
* The result will also be used to determine the value of `hasPreviousPage`.
126136
*/
127-
getPreviousPageParam?: GetPreviousPageParamFunction<TQueryFnData>
137+
getPreviousPageParam?: GetPreviousPageParamFunction<TPageParam, TQueryFnData>
128138
/**
129139
* This function can be set to automatically get the next cursor for infinite queries.
130140
* The result will also be used to determine the value of `hasNextPage`.
131141
*/
132-
getNextPageParam: GetNextPageParamFunction<TQueryFnData>
142+
getNextPageParam: GetNextPageParamFunction<TPageParam, TQueryFnData>
133143
}
134144

135145
export type ThrowErrors<
@@ -150,7 +160,14 @@ export interface QueryObserverOptions<
150160
TData = TQueryFnData,
151161
TQueryData = TQueryFnData,
152162
TQueryKey extends QueryKey = QueryKey,
153-
> extends QueryOptions<TQueryFnData, TError, TQueryData, TQueryKey> {
163+
TPageParam = never,
164+
> extends QueryOptions<
165+
TQueryFnData,
166+
TError,
167+
TQueryData,
168+
TQueryKey,
169+
TPageParam
170+
> {
154171
/**
155172
* Set this to `false` to disable automatic refetching when the query mounts or changes query keys.
156173
* To refetch the query, use the `refetch` method returned from the `useQuery` instance.
@@ -289,14 +306,16 @@ export interface InfiniteQueryObserverOptions<
289306
TData = TQueryFnData,
290307
TQueryData = TQueryFnData,
291308
TQueryKey extends QueryKey = QueryKey,
309+
TPageParam = unknown,
292310
> extends QueryObserverOptions<
293311
TQueryFnData,
294312
TError,
295313
InfiniteData<TData>,
296314
InfiniteData<TQueryData>,
297-
TQueryKey
315+
TQueryKey,
316+
TPageParam
298317
>,
299-
InfiniteQueryOptions<TQueryFnData> {}
318+
InfiniteQueryOptions<TQueryFnData, TPageParam> {}
300319

301320
export type DefaultedInfiniteQueryObserverOptions<
302321
TQueryFnData = unknown,
@@ -320,8 +339,9 @@ export interface FetchQueryOptions<
320339
TError = RegisteredError,
321340
TData = TQueryFnData,
322341
TQueryKey extends QueryKey = QueryKey,
342+
TPageParam = never,
323343
> extends WithRequired<
324-
QueryOptions<TQueryFnData, TError, TData, TQueryKey>,
344+
QueryOptions<TQueryFnData, TError, TData, TQueryKey, TPageParam>,
325345
'queryKey'
326346
> {
327347
/**
@@ -336,13 +356,15 @@ export interface FetchInfiniteQueryOptions<
336356
TError = RegisteredError,
337357
TData = TQueryFnData,
338358
TQueryKey extends QueryKey = QueryKey,
359+
TPageParam = unknown,
339360
> extends FetchQueryOptions<
340361
TQueryFnData,
341362
TError,
342363
InfiniteData<TData>,
343-
TQueryKey
364+
TQueryKey,
365+
TPageParam
344366
>,
345-
DefaultPageParam {}
367+
DefaultPageParam<TPageParam> {}
346368

347369
export interface ResultOptions {
348370
throwOnError?: boolean

packages/react-query/src/types.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,13 +41,15 @@ export interface UseInfiniteQueryOptions<
4141
TData = TQueryFnData,
4242
TQueryData = TQueryFnData,
4343
TQueryKey extends QueryKey = QueryKey,
44+
TPageParam = unknown,
4445
> extends WithRequired<
4546
InfiniteQueryObserverOptions<
4647
TQueryFnData,
4748
TError,
4849
TData,
4950
TQueryData,
50-
TQueryKey
51+
TQueryKey,
52+
TPageParam
5153
>,
5254
'queryKey'
5355
> {}

packages/react-query/src/useInfiniteQuery.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,15 @@ export function useInfiniteQuery<
1414
TError = RegisteredError,
1515
TData = TQueryFnData,
1616
TQueryKey extends QueryKey = QueryKey,
17+
TPageParam = unknown,
1718
>(
1819
options: UseInfiniteQueryOptions<
1920
TQueryFnData,
2021
TError,
2122
TData,
2223
TQueryFnData,
23-
TQueryKey
24+
TQueryKey,
25+
TPageParam
2426
>,
2527
queryClient?: QueryClient,
2628
): UseInfiniteQueryResult<TData, TError> {

0 commit comments

Comments
 (0)