Skip to content

Commit 0ed9cd2

Browse files
committed
Separate QueryArg and PageParam types for infinite queries
1 parent dda12a3 commit 0ed9cd2

File tree

8 files changed

+161
-79
lines changed

8 files changed

+161
-79
lines changed

packages/toolkit/src/query/core/apiState.ts

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ import type {
77
BaseEndpointDefinition,
88
ResultTypeFrom,
99
QueryArgFrom,
10+
InfiniteQueryDefinition,
11+
PageParamFrom,
1012
} from '../endpointDefinitions'
1113
import type { Id, WithRequiredProp } from '../tsHelpers'
1214

@@ -28,24 +30,21 @@ export type RefetchConfigOptions = {
2830
refetchOnFocus: boolean
2931
}
3032

31-
export type GetNextPageParamFunction<TPageParam, TQueryFnData = unknown> = (
33+
export type GetNextPageParamFunction<TPageParam, TQueryFnData> = (
3234
lastPage: TQueryFnData,
3335
allPages: Array<TQueryFnData>,
3436
lastPageParam: TPageParam,
3537
allPageParams: Array<TPageParam>,
3638
) => TPageParam | undefined | null
3739

38-
export type GetPreviousPageParamFunction<TPageParam, TQueryFnData = unknown> = (
40+
export type GetPreviousPageParamFunction<TPageParam, TQueryFnData> = (
3941
firstPage: TQueryFnData,
4042
allPages: Array<TQueryFnData>,
4143
firstPageParam: TPageParam,
4244
allPageParams: Array<TPageParam>,
4345
) => TPageParam | undefined | null
4446

45-
export type InfiniteQueryConfigOptions<
46-
TQueryFnData = unknown,
47-
TPageParam = unknown,
48-
> = {
47+
export type InfiniteQueryConfigOptions<TQueryFnData, TPageParam> = {
4948
/**
5049
* This function can be set to automatically get the previous cursor for infinite queries.
5150
* The result will also be used to determine the value of `hasPreviousPage`.
@@ -54,7 +53,7 @@ export type InfiniteQueryConfigOptions<
5453
getNextPageParam: GetNextPageParamFunction<TPageParam, TQueryFnData>
5554
}
5655

57-
export interface InfiniteData<TData, TPageParam = unknown> {
56+
export interface InfiniteData<TData, TPageParam> {
5857
pages: Array<TData>
5958
pageParams: Array<TPageParam>
6059
}
@@ -239,15 +238,18 @@ export type QuerySubState<
239238

240239
export type InfiniteQuerySubState<
241240
D extends BaseEndpointDefinition<any, any, any>,
242-
> = QuerySubState<D, InfiniteData<ResultTypeFrom<D>>> & {
243-
// TODO: These shouldn't be optional
244-
hasNextPage?: boolean
245-
hasPreviousPage?: boolean
246-
isFetchingNextPage?: boolean
247-
isFetchingPreviousPage?: boolean
248-
param?: QueryArgFrom<D>
249-
direction?: 'forward' | 'backwards'
250-
}
241+
> =
242+
D extends InfiniteQueryDefinition<any, any, any, any, any>
243+
? QuerySubState<D, InfiniteData<ResultTypeFrom<D>, PageParamFrom<D>>> & {
244+
// TODO: These shouldn't be optional
245+
hasNextPage?: boolean
246+
hasPreviousPage?: boolean
247+
isFetchingNextPage?: boolean
248+
isFetchingPreviousPage?: boolean
249+
param?: PageParamFrom<D>
250+
direction?: 'forward' | 'backwards'
251+
}
252+
: never
251253

252254
type BaseMutationSubState<D extends BaseEndpointDefinition<any, any, any>> = {
253255
requestId: string

packages/toolkit/src/query/core/buildInitiate.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import type { BaseQueryError, QueryReturnValue } from '../baseQueryTypes'
1212
import type { InternalSerializeQueryArgs } from '../defaultSerializeQueryArgs'
1313
import type {
1414
EndpointDefinitions,
15+
InfiniteQueryArgFrom,
1516
InfiniteQueryDefinition,
1617
MutationDefinition,
1718
QueryArgFrom,
@@ -70,7 +71,7 @@ export type StartInfiniteQueryActionCreatorOptions = {
7071
subscribe?: boolean
7172
forceRefetch?: boolean | number
7273
subscriptionOptions?: SubscriptionOptions
73-
infiniteQueryOptions?: InfiniteQueryConfigOptions
74+
infiniteQueryOptions?: InfiniteQueryConfigOptions<unknown, unknown>
7475
direction?: 'forward' | 'backwards'
7576
[forceQueryFnSymbol]?: () => QueryReturnValue
7677
param?: unknown
@@ -89,7 +90,7 @@ type StartQueryActionCreator<
8990
type StartInfiniteQueryActionCreator<
9091
D extends InfiniteQueryDefinition<any, any, any, any, any>,
9192
> = (
92-
arg: QueryArgFrom<D>,
93+
arg: InfiniteQueryArgFrom<D>,
9394
options?: StartInfiniteQueryActionCreatorOptions,
9495
) => (
9596
dispatch: ThunkDispatch<any, any, UnknownAction>,
@@ -111,7 +112,7 @@ export type QueryActionCreatorResult<
111112
}
112113

113114
export type InfiniteQueryActionCreatorResult<
114-
D extends InfiniteQueryDefinition<any, any, any, any>,
115+
D extends InfiniteQueryDefinition<any, any, any, any, any>,
115116
> = Promise<InfiniteQueryResultSelectorResult<D>> & {
116117
arg: QueryArgFrom<D>
117118
requestId: string
@@ -479,7 +480,7 @@ You must add the middleware for RTK-Query to function correctly!`,
479480

480481
function buildInitiateInfiniteQuery(
481482
endpointName: string,
482-
endpointDefinition: InfiniteQueryDefinition<any, any, any, any>,
483+
endpointDefinition: InfiniteQueryDefinition<any, any, any, any, any>,
483484
pages?: number,
484485
) {
485486
const infiniteQueryAction: StartInfiniteQueryActionCreator<any> =

packages/toolkit/src/query/core/buildSelectors.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -105,14 +105,14 @@ export type QueryResultSelectorResult<
105105
> = QuerySubState<Definition> & RequestStatusFlags
106106

107107
type InfiniteQueryResultSelectorFactory<
108-
Definition extends InfiniteQueryDefinition<any, any, any, any>,
108+
Definition extends InfiniteQueryDefinition<any, any, any, any, any>,
109109
RootState,
110110
> = (
111111
queryArg: QueryArgFrom<Definition> | SkipToken,
112112
) => (state: RootState) => InfiniteQueryResultSelectorResult<Definition>
113113

114114
export type InfiniteQueryResultSelectorResult<
115-
Definition extends InfiniteQueryDefinition<any, any, any, any>,
115+
Definition extends InfiniteQueryDefinition<any, any, any, any, any>,
116116
> = InfiniteQuerySubState<Definition> & RequestStatusFlags
117117

118118
type MutationResultSelectorFactory<
@@ -215,7 +215,7 @@ export function buildSelectors<
215215
// selector currently is just a clone of Query though
216216
function buildInfiniteQuerySelector(
217217
endpointName: string,
218-
endpointDefinition: InfiniteQueryDefinition<any, any, any, any>,
218+
endpointDefinition: InfiniteQueryDefinition<any, any, any, any, any>,
219219
) {
220220
return ((queryArgs: any) => {
221221
const serializedArgs = serializeQueryArgs({

packages/toolkit/src/query/core/buildThunks.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -429,7 +429,7 @@ export function buildThunks<
429429
// Infinite query wrapper, which executes the request and returns
430430
// the InfiniteData `{pages, pageParams}` structure
431431
const fetchPage = async (
432-
data: InfiniteData<unknown>,
432+
data: InfiniteData<unknown, unknown>,
433433
param: unknown,
434434
previous?: boolean,
435435
): Promise<QueryReturnValue> => {
@@ -575,10 +575,10 @@ export function buildThunks<
575575
for (let i = 1; i < remainingPages; i++) {
576576
const param = getNextPageParam(
577577
endpointDefinition.infiniteQueryOptions,
578-
result.data as InfiniteData<unknown>,
578+
result.data as InfiniteData<unknown, unknown>,
579579
)
580580
result = await fetchPage(
581-
result.data as InfiniteData<unknown>,
581+
result.data as InfiniteData<unknown, unknown>,
582582
param,
583583
)
584584
}
@@ -638,8 +638,8 @@ In the case of an unhandled error, no tags will be "provided" or "invalidated".`
638638
}
639639

640640
function getNextPageParam(
641-
options: InfiniteQueryConfigOptions<any>,
642-
{ pages, pageParams }: InfiniteData<unknown>,
641+
options: InfiniteQueryConfigOptions<unknown, unknown>,
642+
{ pages, pageParams }: InfiniteData<unknown, unknown>,
643643
): unknown | undefined {
644644
const lastIndex = pages.length - 1
645645
return options.getNextPageParam(
@@ -651,8 +651,8 @@ In the case of an unhandled error, no tags will be "provided" or "invalidated".`
651651
}
652652

653653
function getPreviousPageParam(
654-
options: InfiniteQueryConfigOptions<any>,
655-
{ pages, pageParams }: InfiniteData<unknown>,
654+
options: InfiniteQueryConfigOptions<unknown, unknown>,
655+
{ pages, pageParams }: InfiniteData<unknown, unknown>,
656656
): unknown | undefined {
657657
return options.getPreviousPageParam?.(
658658
pages[0],

packages/toolkit/src/query/endpointDefinitions.ts

Lines changed: 42 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ import type {
3535
OmitFromUnion,
3636
UnwrapPromise,
3737
} from './tsHelpers'
38+
import { AnyARecord } from 'dns'
3839

3940
const resultType = /* @__PURE__ */ Symbol()
4041
const baseQuery = /* @__PURE__ */ Symbol()
@@ -43,6 +44,7 @@ type EndpointDefinitionWithQuery<
4344
QueryArg,
4445
BaseQuery extends BaseQueryFn,
4546
ResultType,
47+
PageParam = never,
4648
> = {
4749
/**
4850
* `query` can be a function that returns either a `string` or an `object` which is passed to your `baseQuery`. If you are using [fetchBaseQuery](./fetchBaseQuery), this can return either a `string` or an `object` of properties in `FetchArgs`. If you use your own custom [`baseQuery`](../../rtk-query/usage/customizing-queries), you can customize this behavior to your liking.
@@ -546,6 +548,7 @@ export type QueryDefinition<
546548
// cloning Query Endpoint Definition with an extra option to begin with
547549
export interface InfiniteQueryTypes<
548550
QueryArg,
551+
PageParam,
549552
BaseQuery extends BaseQueryFn,
550553
TagTypes extends string,
551554
ResultType,
@@ -560,6 +563,7 @@ export interface InfiniteQueryTypes<
560563
*/
561564
InfiniteQueryDefinition: InfiniteQueryDefinition<
562565
QueryArg,
566+
PageParam,
563567
BaseQuery,
564568
TagTypes,
565569
ResultType,
@@ -573,6 +577,7 @@ export interface InfiniteQueryExtraOptions<
573577
TagTypes extends string,
574578
ResultType,
575579
QueryArg,
580+
PageParam,
576581
BaseQuery extends BaseQueryFn,
577582
ReducerPath extends string = string,
578583
> extends CacheLifecycleInfiniteQueryExtraOptions<
@@ -664,6 +669,7 @@ export interface InfiniteQueryExtraOptions<
664669
*/
665670
Types?: InfiniteQueryTypes<
666671
QueryArg,
672+
PageParam,
667673
BaseQuery,
668674
TagTypes,
669675
ResultType,
@@ -673,18 +679,22 @@ export interface InfiniteQueryExtraOptions<
673679

674680
export type InfiniteQueryDefinition<
675681
QueryArg,
682+
PageParam,
676683
BaseQuery extends BaseQueryFn,
677684
TagTypes extends string,
678685
ResultType,
679686
ReducerPath extends string = string,
680-
> = BaseEndpointDefinition<QueryArg, BaseQuery, ResultType> &
681-
InfiniteQueryExtraOptions<
682-
TagTypes,
683-
ResultType,
684-
QueryArg,
685-
BaseQuery,
686-
ReducerPath
687-
>
687+
> =
688+
// Intentionally use `PageParam` as the QueryArg` type
689+
BaseEndpointDefinition<PageParam, BaseQuery, ResultType> &
690+
InfiniteQueryExtraOptions<
691+
TagTypes,
692+
ResultType,
693+
QueryArg,
694+
PageParam,
695+
BaseQuery,
696+
ReducerPath
697+
>
688698

689699
type MutationTypes<
690700
QueryArg,
@@ -812,11 +822,13 @@ export type EndpointDefinition<
812822
TagTypes extends string,
813823
ResultType,
814824
ReducerPath extends string = string,
825+
PageParam = any,
815826
> =
816827
| QueryDefinition<QueryArg, BaseQuery, TagTypes, ResultType, ReducerPath>
817828
| MutationDefinition<QueryArg, BaseQuery, TagTypes, ResultType, ReducerPath>
818829
| InfiniteQueryDefinition<
819830
QueryArg,
831+
PageParam,
820832
BaseQuery,
821833
TagTypes,
822834
ResultType,
@@ -842,7 +854,7 @@ export function isMutationDefinition(
842854

843855
export function isInfiniteQueryDefinition(
844856
e: EndpointDefinition<any, any, any, any>,
845-
): e is InfiniteQueryDefinition<any, any, any, any> {
857+
): e is InfiniteQueryDefinition<any, any, any, any, any> {
846858
return e.type === DefinitionType.infinitequery
847859
}
848860

@@ -922,10 +934,11 @@ export type EndpointBuilder<
922934
>,
923935
): MutationDefinition<QueryArg, BaseQuery, TagTypes, ResultType, ReducerPath>
924936

925-
infiniteQuery<ResultType, QueryArg>(
937+
infiniteQuery<ResultType, QueryArg, PageParam>(
926938
definition: OmitFromUnion<
927939
InfiniteQueryDefinition<
928940
QueryArg,
941+
PageParam,
929942
BaseQuery,
930943
TagTypes,
931944
ResultType,
@@ -935,6 +948,7 @@ export type EndpointBuilder<
935948
>,
936949
): InfiniteQueryDefinition<
937950
QueryArg,
951+
PageParam,
938952
BaseQuery,
939953
TagTypes,
940954
ResultType,
@@ -981,7 +995,15 @@ export function expandTagDescription(
981995
}
982996

983997
export type QueryArgFrom<D extends BaseEndpointDefinition<any, any, any>> =
984-
D extends BaseEndpointDefinition<infer QA, any, any> ? QA : unknown
998+
D extends BaseEndpointDefinition<infer QA, any, any> ? QA : never
999+
1000+
// Just extracting `QueryArg` from `BaseEndpointDefinition`
1001+
// doesn't sufficiently match here.
1002+
// We need to explicitly match against `InfiniteQueryDefinition`
1003+
export type InfiniteQueryArgFrom<
1004+
D extends BaseEndpointDefinition<any, any, any>,
1005+
> = D extends InfiniteQueryDefinition<infer QA, any, any, any, any> ? QA : never
1006+
9851007
export type ResultTypeFrom<D extends BaseEndpointDefinition<any, any, any>> =
9861008
D extends BaseEndpointDefinition<any, any, infer RT> ? RT : unknown
9871009

@@ -992,6 +1014,11 @@ export type ReducerPathFrom<
9921014
export type TagTypesFrom<D extends EndpointDefinition<any, any, any, any>> =
9931015
D extends EndpointDefinition<any, any, infer RP, any> ? RP : unknown
9941016

1017+
export type PageParamFrom<
1018+
D extends InfiniteQueryDefinition<any, any, any, any, any>,
1019+
> =
1020+
D extends InfiniteQueryDefinition<any, infer PP, any, any, any> ? PP : unknown
1021+
9951022
export type TagTypesFromApi<T> =
9961023
T extends Api<any, any, any, infer TagTypes> ? TagTypes : never
9971024

@@ -1035,13 +1062,15 @@ export type OverrideResultType<Definition, NewResultType> =
10351062
>
10361063
: Definition extends InfiniteQueryDefinition<
10371064
infer QueryArg,
1065+
infer PageParam,
10381066
infer BaseQuery,
10391067
infer TagTypes,
10401068
any,
10411069
infer ReducerPath
10421070
>
10431071
? InfiniteQueryDefinition<
10441072
QueryArg,
1073+
PageParam,
10451074
BaseQuery,
10461075
TagTypes,
10471076
NewResultType,
@@ -1084,13 +1113,15 @@ export type UpdateDefinitions<
10841113
>
10851114
: Definitions[K] extends InfiniteQueryDefinition<
10861115
infer QueryArg,
1116+
infer PageParam,
10871117
infer BaseQuery,
10881118
any,
10891119
infer ResultType,
10901120
infer ReducerPath
10911121
>
10921122
? InfiniteQueryDefinition<
10931123
QueryArg,
1124+
PageParam,
10941125
BaseQuery,
10951126
NewTagTypes,
10961127
TransformedResponse<NewDefinitions, K, ResultType>,

0 commit comments

Comments
 (0)