@@ -6,8 +6,11 @@ import { QueriesObserver } from '../core/queriesObserver'
66import { useQueryClient } from './QueryClientProvider'
77import { UseQueryOptions , UseQueryResult } from './types'
88
9+ // Avoid TS depth-limit error in case of large array literal
10+ type MAXIMUM_DEPTH = 20
11+
912type GetOptions < T extends any > =
10- // Map params from object {queryFnData: TQueryFnData, error: TError, data: TData}
13+ // Part 1: responsible for applying explicit type parameter to function arguments, if object { queryFnData: TQueryFnData, error: TError, data: TData }
1114 T extends {
1215 queryFnData : infer TQueryFnData
1316 error ?: infer TError
@@ -18,14 +21,14 @@ type GetOptions<T extends any> =
1821 ? UseQueryOptions < TQueryFnData , TError >
1922 : T extends { data : infer TData ; error ?: infer TError }
2023 ? UseQueryOptions < unknown , TError , TData >
21- : // Map params from tuple [TQueryFnData, TError, TData]
24+ : // Part 2: responsible for applying explicit type parameter to function arguments, if tuple [TQueryFnData, TError, TData]
2225 T extends [ infer TQueryFnData , infer TError , infer TData ]
2326 ? UseQueryOptions < TQueryFnData , TError , TData >
2427 : T extends [ infer TQueryFnData , infer TError ]
2528 ? UseQueryOptions < TQueryFnData , TError >
2629 : T extends [ infer TQueryFnData ]
2730 ? UseQueryOptions < TQueryFnData >
28- : // Otherwise try to infer raw argument types
31+ : // Part 3: responsible for inferring and enforcing type if no explicit parameter was provided
2932 T extends {
3033 queryFn ?: QueryFunction < infer TQueryFnData >
3134 select : ( data : any ) => infer TData
@@ -37,36 +40,33 @@ type GetOptions<T extends any> =
3740 UseQueryOptions
3841
3942type GetResults < T > =
40- // Map explicit type-object to results
43+ // Part 1: responsible for mapping explicit type parameter to function result, if object
4144 T extends { queryFnData : any ; error ?: infer TError ; data : infer TData }
4245 ? UseQueryResult < TData , TError >
4346 : T extends { queryFnData : infer TQueryFnData ; error ?: infer TError }
4447 ? UseQueryResult < TQueryFnData , TError >
4548 : T extends { data : infer TData ; error ?: infer TError }
4649 ? UseQueryResult < TData , TError >
47- : // Map explicit type-tuple to results
50+ : // Part 2: responsible for mapping explicit type parameter to function result, if tuple
4851 T extends [ any , infer TError , infer TData ]
4952 ? UseQueryResult < TData , TError >
5053 : T extends [ infer TQueryFnData , infer TError ]
5154 ? UseQueryResult < TQueryFnData , TError >
5255 : T extends [ infer TQueryFnData ]
5356 ? UseQueryResult < TQueryFnData >
54- : // Otherwise map inferred type to results
55- T extends { queryFn ?: QueryFunction < any > ; select : ( data : any ) => infer TData }
57+ : // Part 3: responsible for mapping inferred type to results, if no explicit parameter was provided
58+ T extends {
59+ queryFn ?: QueryFunction < any >
60+ select : ( data : any ) => infer TData
61+ }
5662 ? UseQueryResult < TData >
5763 : T extends { queryFn ?: QueryFunction < infer TQueryFnData > }
5864 ? UseQueryResult < TQueryFnData >
5965 : // Fallback
6066 UseQueryResult
6167
6268/**
63- * In case of very large array literal, revert to UseQueryOptions[]/UseQueryResult[] to avoid TS depth-limit error
64- * note: limit does not apply in case of Array.map() argument
65- */
66- type MAXIMUM_DEPTH = 20
67-
68- /**
69- * Step 1: reducer infers T from mapped param type
69+ * QueriesOptions reducer recursively unwraps function arguments to infer/enforce type param
7070 */
7171type QueriesOptions <
7272 T extends any [ ] ,
@@ -80,19 +80,17 @@ type QueriesOptions<
8080 ? [ ...Result , GetOptions < Head > ]
8181 : T extends [ infer Head , ...infer Tail ]
8282 ? QueriesOptions < [ ...Tail ] , [ ...Result , GetOptions < Head > ] , [ ...Depth , 1 ] >
83- // Differentiate between fixed and dynamic array param type:
84- // with dynamic array, TS can't stop the recursion, so keeps going until T = [] which fails this check
85- : UseQueryOptions [ ] extends T
86- // Mapped tuple (keep the entire structure and try to unwrap in Step 2)
83+ : unknown [ ] extends T
8784 ? T
88- // Dynamic (but homogenous) array
89- : T extends UseQueryOptions < infer TQueryFnData , infer TError , infer TData > [ ]
85+ : // If T is *some* array but we couldn't assign unknown[] to it, then it must hold some known/homogenous type!
86+ // use this to infer the param types in the case of Array.map() argument
87+ T extends UseQueryOptions < infer TQueryFnData , infer TError , infer TData > [ ]
9088 ? UseQueryOptions < TQueryFnData , TError , TData > [ ]
91- // Fallback
92- : UseQueryOptions [ ]
89+ : // Fallback
90+ UseQueryOptions [ ]
9391
9492/**
95- * Step 2: reducer unwraps inferred type T to results
93+ * QueriesResults reducer recursively maps type param to results
9694 */
9795type QueriesResults <
9896 T extends any [ ] ,
@@ -106,11 +104,11 @@ type QueriesResults<
106104 ? [ ...Result , GetResults < Head > ]
107105 : T extends [ infer Head , ...infer Tail ]
108106 ? QueriesResults < [ ...Tail ] , [ ...Result , GetResults < Head > ] , [ ...Depth , 1 ] >
109- // Handle Array.map()
110- : T extends UseQueryOptions < infer TQueryFnData , infer TError , infer TData > [ ] ?
111- UseQueryResult < unknown extends TData ? TQueryFnData : TData , TError > [ ]
112- // Fallback
113- : UseQueryResult [ ]
107+ : T extends UseQueryOptions < infer TQueryFnData , infer TError , infer TData > [ ]
108+ ? // Dynamic-size (homogenous) UseQueryOptions array: map directly to array of results
109+ UseQueryResult < unknown extends TData ? TQueryFnData : TData , TError > [ ]
110+ : // Fallback
111+ UseQueryResult [ ]
114112
115113export function useQueries < T extends any [ ] > (
116114 queries : readonly [ ...QueriesOptions < T > ]
0 commit comments