@tanstack/react-query 5.0.0-beta.2 → 5.0.0-beta.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (99) hide show
  1. package/build/legacy/index.cjs +3 -0
  2. package/build/legacy/index.cjs.map +1 -1
  3. package/build/legacy/index.d.cts +3 -2
  4. package/build/legacy/index.d.ts +3 -2
  5. package/build/legacy/index.js +2 -0
  6. package/build/legacy/index.js.map +1 -1
  7. package/build/legacy/infiniteQueryOptions.cjs.map +1 -1
  8. package/build/legacy/infiniteQueryOptions.d.cts +1 -1
  9. package/build/legacy/infiniteQueryOptions.d.ts +1 -1
  10. package/build/legacy/infiniteQueryOptions.js.map +1 -1
  11. package/build/legacy/queryOptions.cjs.map +1 -1
  12. package/build/legacy/queryOptions.d.cts +4 -3
  13. package/build/legacy/queryOptions.d.ts +4 -3
  14. package/build/legacy/queryOptions.js.map +1 -1
  15. package/build/legacy/types.cjs.map +1 -1
  16. package/build/legacy/types.d.cts +4 -4
  17. package/build/legacy/types.d.ts +4 -4
  18. package/build/legacy/useInfiniteQuery.cjs.map +1 -1
  19. package/build/legacy/useInfiniteQuery.d.cts +2 -1
  20. package/build/legacy/useInfiniteQuery.d.ts +2 -1
  21. package/build/legacy/useInfiniteQuery.js.map +1 -1
  22. package/build/legacy/useQueries.cjs.map +1 -1
  23. package/build/legacy/useQueries.d.cts +4 -4
  24. package/build/legacy/useQueries.d.ts +4 -4
  25. package/build/legacy/useQueries.js.map +1 -1
  26. package/build/legacy/useQuery.cjs.map +1 -1
  27. package/build/legacy/useQuery.d.cts +2 -1
  28. package/build/legacy/useQuery.d.ts +2 -1
  29. package/build/legacy/useQuery.js.map +1 -1
  30. package/build/legacy/useSuspenseQueries.cjs +46 -0
  31. package/build/legacy/useSuspenseQueries.cjs.map +1 -0
  32. package/build/legacy/useSuspenseQueries.d.cts +66 -0
  33. package/build/legacy/useSuspenseQueries.d.ts +66 -0
  34. package/build/legacy/useSuspenseQueries.js +22 -0
  35. package/build/legacy/useSuspenseQueries.js.map +1 -0
  36. package/build/legacy/utils.cjs.map +1 -1
  37. package/build/legacy/utils.d.cts +1 -1
  38. package/build/legacy/utils.d.ts +1 -1
  39. package/build/legacy/utils.js.map +1 -1
  40. package/build/modern/index.cjs +3 -0
  41. package/build/modern/index.cjs.map +1 -1
  42. package/build/modern/index.d.cts +3 -2
  43. package/build/modern/index.d.ts +3 -2
  44. package/build/modern/index.js +2 -0
  45. package/build/modern/index.js.map +1 -1
  46. package/build/modern/infiniteQueryOptions.cjs.map +1 -1
  47. package/build/modern/infiniteQueryOptions.d.cts +1 -1
  48. package/build/modern/infiniteQueryOptions.d.ts +1 -1
  49. package/build/modern/infiniteQueryOptions.js.map +1 -1
  50. package/build/modern/queryOptions.cjs.map +1 -1
  51. package/build/modern/queryOptions.d.cts +4 -3
  52. package/build/modern/queryOptions.d.ts +4 -3
  53. package/build/modern/queryOptions.js.map +1 -1
  54. package/build/modern/types.cjs.map +1 -1
  55. package/build/modern/types.d.cts +4 -4
  56. package/build/modern/types.d.ts +4 -4
  57. package/build/modern/useInfiniteQuery.cjs.map +1 -1
  58. package/build/modern/useInfiniteQuery.d.cts +2 -1
  59. package/build/modern/useInfiniteQuery.d.ts +2 -1
  60. package/build/modern/useInfiniteQuery.js.map +1 -1
  61. package/build/modern/useQueries.cjs.map +1 -1
  62. package/build/modern/useQueries.d.cts +4 -4
  63. package/build/modern/useQueries.d.ts +4 -4
  64. package/build/modern/useQueries.js.map +1 -1
  65. package/build/modern/useQuery.cjs.map +1 -1
  66. package/build/modern/useQuery.d.cts +2 -1
  67. package/build/modern/useQuery.d.ts +2 -1
  68. package/build/modern/useQuery.js.map +1 -1
  69. package/build/modern/useSuspenseQueries.cjs +46 -0
  70. package/build/modern/useSuspenseQueries.cjs.map +1 -0
  71. package/build/modern/useSuspenseQueries.d.cts +66 -0
  72. package/build/modern/useSuspenseQueries.d.ts +66 -0
  73. package/build/modern/useSuspenseQueries.js +22 -0
  74. package/build/modern/useSuspenseQueries.js.map +1 -0
  75. package/build/modern/utils.cjs.map +1 -1
  76. package/build/modern/utils.d.cts +1 -1
  77. package/build/modern/utils.d.ts +1 -1
  78. package/build/modern/utils.js.map +1 -1
  79. package/package.json +8 -4
  80. package/src/__tests__/QueryResetErrorBoundary.test.tsx +10 -6
  81. package/src/__tests__/ssr.test.tsx +2 -2
  82. package/src/__tests__/suspense.test.tsx +34 -393
  83. package/src/__tests__/useInfiniteQuery.test.tsx +44 -44
  84. package/src/__tests__/useInfiniteQuery.type.test.tsx +24 -13
  85. package/src/__tests__/useIsFetching.test.tsx +2 -2
  86. package/src/__tests__/useMutation.test.tsx +4 -4
  87. package/src/__tests__/useMutationState.test.tsx +4 -4
  88. package/src/__tests__/useQueries.test.tsx +14 -12
  89. package/src/__tests__/useQuery.test.tsx +109 -80
  90. package/src/__tests__/useQuery.types.test.tsx +36 -55
  91. package/src/index.ts +13 -0
  92. package/src/infiniteQueryOptions.ts +3 -1
  93. package/src/queryOptions.ts +19 -7
  94. package/src/types.ts +18 -12
  95. package/src/useInfiniteQuery.ts +7 -2
  96. package/src/useQueries.ts +34 -28
  97. package/src/useQuery.ts +3 -1
  98. package/src/useSuspenseQueries.ts +163 -0
  99. package/src/utils.ts +1 -1
@@ -1,6 +1,7 @@
1
1
  import { useQuery } from '../useQuery'
2
2
  import { queryOptions } from '../queryOptions'
3
3
  import { doNotExecute } from './utils'
4
+ import type { UseQueryOptions } from '../types'
4
5
  import type { Equal, Expect } from './utils'
5
6
 
6
7
  describe('initialData', () => {
@@ -44,6 +45,19 @@ describe('initialData', () => {
44
45
  })
45
46
  })
46
47
 
48
+ it('it should be possible to define a different TData than TQueryFnData using select with queryOptions spread into useQuery', () => {
49
+ doNotExecute(() => {
50
+ const options = queryOptions({
51
+ queryKey: ['key'],
52
+ queryFn: () => Promise.resolve(1),
53
+ })
54
+ useQuery({
55
+ ...options,
56
+ select: (data) => data > 1,
57
+ })
58
+ })
59
+ })
60
+
47
61
  it('TData should always be defined when initialData is provided as a function which ALWAYS returns the data', () => {
48
62
  doNotExecute(() => {
49
63
  const { data } = useQuery({
@@ -97,79 +111,46 @@ describe('initialData', () => {
97
111
  return result
98
112
  })
99
113
  })
100
- })
101
-
102
- describe('Query key overload', () => {
103
- it('TData should always be defined when initialData is provided', () => {
104
- doNotExecute(() => {
105
- const { data } = useQuery({
106
- queryKey: ['key'],
107
- queryFn: () => {
108
- return {
109
- wow: true,
110
- }
111
- },
112
- initialData: {
113
- wow: true,
114
- },
115
- })
116
-
117
- const result: Expect<Equal<{ wow: boolean }, typeof data>> = true
118
- return result
119
- })
120
- })
121
114
 
122
- it('TData should have undefined in the union when initialData is NOT provided', () => {
115
+ it('TData should be narrowed after an isSuccess check when initialData is provided as a function which can return undefined', () => {
123
116
  doNotExecute(() => {
124
- const { data } = useQuery({
117
+ const { data, isSuccess } = useQuery({
125
118
  queryKey: ['key'],
126
119
  queryFn: () => {
127
120
  return {
128
121
  wow: true,
129
122
  }
130
123
  },
124
+ initialData: () => undefined as { wow: boolean } | undefined,
131
125
  })
132
126
 
133
- const result: Expect<Equal<{ wow: boolean } | undefined, typeof data>> =
134
- true
135
- return result
127
+ if (isSuccess) {
128
+ const result: Expect<Equal<{ wow: boolean }, typeof data>> = true
129
+ return result
130
+ }
131
+ return false
136
132
  })
137
133
  })
138
134
  })
139
135
 
140
- describe('Query key and func', () => {
141
- it('TData should always be defined when initialData is provided', () => {
136
+ describe('custom hook', () => {
137
+ it('should allow custom hooks using UseQueryOptions', () => {
142
138
  doNotExecute(() => {
143
- const { data } = useQuery({
144
- queryKey: ['key'],
145
- queryFn: () => {
146
- return {
147
- wow: true,
148
- }
149
- },
150
- initialData: {
151
- wow: true,
152
- },
153
- })
139
+ type Data = string
154
140
 
155
- const result: Expect<Equal<{ wow: boolean }, typeof data>> = true
156
- return result
157
- })
158
- })
141
+ const useCustomQuery = (
142
+ options?: Omit<UseQueryOptions<Data>, 'queryKey' | 'queryFn'>,
143
+ ) => {
144
+ return useQuery({
145
+ ...options,
146
+ queryKey: ['todos-key'],
147
+ queryFn: () => Promise.resolve('data'),
148
+ })
149
+ }
159
150
 
160
- it('TData should have undefined in the union when initialData is NOT provided', () => {
161
- doNotExecute(() => {
162
- const { data } = useQuery({
163
- queryKey: ['key'],
164
- queryFn: () => {
165
- return {
166
- wow: true,
167
- }
168
- },
169
- })
151
+ const { data } = useCustomQuery()
170
152
 
171
- const result: Expect<Equal<{ wow: boolean } | undefined, typeof data>> =
172
- true
153
+ const result: Expect<Equal<Data | undefined, typeof data>> = true
173
154
  return result
174
155
  })
175
156
  })
package/src/index.ts CHANGED
@@ -10,8 +10,21 @@ export type { QueriesResults, QueriesOptions } from './useQueries'
10
10
  export { useQuery } from './useQuery'
11
11
  export { useSuspenseQuery } from './useSuspenseQuery'
12
12
  export { useSuspenseInfiniteQuery } from './useSuspenseInfiniteQuery'
13
+ export { useSuspenseQueries } from './useSuspenseQueries'
14
+ export type {
15
+ SuspenseQueriesResults,
16
+ SuspenseQueriesOptions,
17
+ } from './useSuspenseQueries'
13
18
  export { queryOptions } from './queryOptions'
19
+ export type {
20
+ DefinedInitialDataOptions,
21
+ UndefinedInitialDataOptions,
22
+ } from './queryOptions'
14
23
  export { infiniteQueryOptions } from './infiniteQueryOptions'
24
+ export type {
25
+ DefinedInitialDataInfiniteOptions,
26
+ UndefinedInitialDataInfiniteOptions,
27
+ } from './infiniteQueryOptions'
15
28
  export {
16
29
  QueryClientContext,
17
30
  QueryClientProvider,
@@ -35,7 +35,9 @@ export type DefinedInitialDataInfiniteOptions<
35
35
  TQueryKey,
36
36
  TPageParam
37
37
  > & {
38
- initialData: InfiniteData<TQueryData> | (() => InfiniteData<TQueryData>)
38
+ initialData:
39
+ | InfiniteData<TQueryData, TPageParam>
40
+ | (() => InfiniteData<TQueryData, TPageParam>)
39
41
  }
40
42
 
41
43
  export function infiniteQueryOptions<
@@ -10,13 +10,17 @@ export type UndefinedInitialDataOptions<
10
10
  initialData?: undefined
11
11
  }
12
12
 
13
+ type NonUndefinedGuard<T> = T extends undefined ? never : T
14
+
13
15
  export type DefinedInitialDataOptions<
14
16
  TQueryFnData = unknown,
15
17
  TError = DefaultError,
16
18
  TData = TQueryFnData,
17
19
  TQueryKey extends QueryKey = QueryKey,
18
20
  > = UseQueryOptions<TQueryFnData, TError, TData, TQueryKey> & {
19
- initialData: TQueryFnData | (() => TQueryFnData)
21
+ initialData:
22
+ | NonUndefinedGuard<TQueryFnData>
23
+ | (() => NonUndefinedGuard<TQueryFnData>)
20
24
  }
21
25
 
22
26
  export function queryOptions<
@@ -24,18 +28,26 @@ export function queryOptions<
24
28
  TError = DefaultError,
25
29
  TData = TQueryFnData,
26
30
  TQueryKey extends QueryKey = QueryKey,
27
- >(
28
- options: UndefinedInitialDataOptions<TQueryFnData, TError, TData, TQueryKey>,
29
- ): UndefinedInitialDataOptions<TQueryFnData, TError, TData, TQueryKey>
31
+ TOptions extends UndefinedInitialDataOptions<
32
+ TQueryFnData,
33
+ TError,
34
+ TData,
35
+ TQueryKey
36
+ > = UndefinedInitialDataOptions<TQueryFnData, TError, TData, TQueryKey>,
37
+ >(options: TOptions): TOptions
30
38
 
31
39
  export function queryOptions<
32
40
  TQueryFnData = unknown,
33
41
  TError = DefaultError,
34
42
  TData = TQueryFnData,
35
43
  TQueryKey extends QueryKey = QueryKey,
36
- >(
37
- options: DefinedInitialDataOptions<TQueryFnData, TError, TData, TQueryKey>,
38
- ): DefinedInitialDataOptions<TQueryFnData, TError, TData, TQueryKey>
44
+ TOptions extends DefinedInitialDataOptions<
45
+ TQueryFnData,
46
+ TError,
47
+ TData,
48
+ TQueryKey
49
+ > = DefinedInitialDataOptions<TQueryFnData, TError, TData, TQueryKey>,
50
+ >(options: TOptions): TOptions
39
51
 
40
52
  export function queryOptions(options: unknown) {
41
53
  return options
package/src/types.ts CHANGED
@@ -33,9 +33,12 @@ export interface UseQueryOptions<
33
33
  TError = DefaultError,
34
34
  TData = TQueryFnData,
35
35
  TQueryKey extends QueryKey = QueryKey,
36
- > extends WithRequired<
37
- UseBaseQueryOptions<TQueryFnData, TError, TData, TQueryFnData, TQueryKey>,
38
- 'queryKey'
36
+ > extends Omit<
37
+ WithRequired<
38
+ UseBaseQueryOptions<TQueryFnData, TError, TData, TQueryFnData, TQueryKey>,
39
+ 'queryKey'
40
+ >,
41
+ 'suspense'
39
42
  > {}
40
43
 
41
44
  export interface UseSuspenseQueryOptions<
@@ -45,7 +48,7 @@ export interface UseSuspenseQueryOptions<
45
48
  TQueryKey extends QueryKey = QueryKey,
46
49
  > extends Omit<
47
50
  UseQueryOptions<TQueryFnData, TError, TData, TQueryKey>,
48
- 'enabled' | 'suspense' | 'throwOnError' | 'placeholderData'
51
+ 'enabled' | 'throwOnError' | 'placeholderData'
49
52
  > {}
50
53
 
51
54
  export interface UseInfiniteQueryOptions<
@@ -56,13 +59,16 @@ export interface UseInfiniteQueryOptions<
56
59
  TQueryKey extends QueryKey = QueryKey,
57
60
  TPageParam = unknown,
58
61
  > extends WithRequired<
59
- InfiniteQueryObserverOptions<
60
- TQueryFnData,
61
- TError,
62
- TData,
63
- TQueryData,
64
- TQueryKey,
65
- TPageParam
62
+ Omit<
63
+ InfiniteQueryObserverOptions<
64
+ TQueryFnData,
65
+ TError,
66
+ TData,
67
+ TQueryData,
68
+ TQueryKey,
69
+ TPageParam
70
+ >,
71
+ 'suspense'
66
72
  >,
67
73
  'queryKey'
68
74
  > {}
@@ -83,7 +89,7 @@ export interface UseSuspenseInfiniteQueryOptions<
83
89
  TQueryKey,
84
90
  TPageParam
85
91
  >,
86
- 'enabled' | 'suspense' | 'throwOnError' | 'placeholderData'
92
+ 'enabled' | 'throwOnError' | 'placeholderData'
87
93
  > {}
88
94
 
89
95
  export type UseBaseQueryResult<
@@ -70,11 +70,16 @@ export function useInfiniteQuery<
70
70
  TPageParam
71
71
  >,
72
72
  queryClient?: QueryClient,
73
- ): UseInfiniteQueryResult<TData, TError> {
73
+ ): UseInfiniteQueryResult<TData, TError>
74
+
75
+ export function useInfiniteQuery(
76
+ options: UseInfiniteQueryOptions,
77
+ queryClient?: QueryClient,
78
+ ) {
74
79
  return useBaseQuery(
75
80
  options,
76
81
  // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
77
82
  InfiniteQueryObserver as typeof QueryObserver,
78
83
  queryClient,
79
- ) as UseInfiniteQueryResult<TData, TError>
84
+ )
80
85
  }
package/src/useQueries.ts CHANGED
@@ -35,7 +35,7 @@ type UseQueryOptionsForUseQueries<
35
35
  TQueryKey extends QueryKey = QueryKey,
36
36
  > = Omit<
37
37
  UseQueryOptions<TQueryFnData, TError, TData, TQueryKey>,
38
- 'placeholderData'
38
+ 'placeholderData' | 'suspense'
39
39
  > & {
40
40
  placeholderData?: TQueryFnData | QueriesPlaceholderDataFunction<TQueryFnData>
41
41
  }
@@ -103,62 +103,68 @@ type GetResults<T> =
103
103
  * QueriesOptions reducer recursively unwraps function arguments to infer/enforce type param
104
104
  */
105
105
  export type QueriesOptions<
106
- T extends any[],
107
- Result extends any[] = [],
106
+ T extends Array<any>,
107
+ Result extends Array<any> = [],
108
108
  Depth extends ReadonlyArray<number> = [],
109
109
  > = Depth['length'] extends MAXIMUM_DEPTH
110
- ? UseQueryOptionsForUseQueries[]
110
+ ? Array<UseQueryOptionsForUseQueries>
111
111
  : T extends []
112
112
  ? []
113
113
  : T extends [infer Head]
114
114
  ? [...Result, GetOptions<Head>]
115
115
  : T extends [infer Head, ...infer Tail]
116
116
  ? QueriesOptions<[...Tail], [...Result, GetOptions<Head>], [...Depth, 1]>
117
- : unknown[] extends T
117
+ : Array<unknown> extends T
118
118
  ? T
119
119
  : // If T is *some* array but we couldn't assign unknown[] to it, then it must hold some known/homogenous type!
120
120
  // use this to infer the param types in the case of Array.map() argument
121
- T extends UseQueryOptionsForUseQueries<
122
- infer TQueryFnData,
123
- infer TError,
124
- infer TData,
125
- infer TQueryKey
126
- >[]
127
- ? UseQueryOptionsForUseQueries<TQueryFnData, TError, TData, TQueryKey>[]
121
+ T extends Array<
122
+ UseQueryOptionsForUseQueries<
123
+ infer TQueryFnData,
124
+ infer TError,
125
+ infer TData,
126
+ infer TQueryKey
127
+ >
128
+ >
129
+ ? Array<UseQueryOptionsForUseQueries<TQueryFnData, TError, TData, TQueryKey>>
128
130
  : // Fallback
129
- UseQueryOptionsForUseQueries[]
131
+ Array<UseQueryOptionsForUseQueries>
130
132
 
131
133
  /**
132
134
  * QueriesResults reducer recursively maps type param to results
133
135
  */
134
136
  export type QueriesResults<
135
- T extends any[],
136
- Result extends any[] = [],
137
+ T extends Array<any>,
138
+ Result extends Array<any> = [],
137
139
  Depth extends ReadonlyArray<number> = [],
138
140
  > = Depth['length'] extends MAXIMUM_DEPTH
139
- ? UseQueryResult[]
141
+ ? Array<UseQueryResult>
140
142
  : T extends []
141
143
  ? []
142
144
  : T extends [infer Head]
143
145
  ? [...Result, GetResults<Head>]
144
146
  : T extends [infer Head, ...infer Tail]
145
147
  ? QueriesResults<[...Tail], [...Result, GetResults<Head>], [...Depth, 1]>
146
- : T extends UseQueryOptionsForUseQueries<
147
- infer TQueryFnData,
148
- infer TError,
149
- infer TData,
150
- any
151
- >[]
148
+ : T extends Array<
149
+ UseQueryOptionsForUseQueries<
150
+ infer TQueryFnData,
151
+ infer TError,
152
+ infer TData,
153
+ any
154
+ >
155
+ >
152
156
  ? // Dynamic-size (homogenous) UseQueryOptions array: map directly to array of results
153
- UseQueryResult<
154
- unknown extends TData ? TQueryFnData : TData,
155
- unknown extends TError ? DefaultError : TError
156
- >[]
157
+ Array<
158
+ UseQueryResult<
159
+ unknown extends TData ? TQueryFnData : TData,
160
+ unknown extends TError ? DefaultError : TError
161
+ >
162
+ >
157
163
  : // Fallback
158
- UseQueryResult[]
164
+ Array<UseQueryResult>
159
165
 
160
166
  export function useQueries<
161
- T extends any[],
167
+ T extends Array<any>,
162
168
  TCombinedResult = QueriesResults<T>,
163
169
  >(
164
170
  {
package/src/useQuery.ts CHANGED
@@ -40,6 +40,8 @@ export function useQuery<
40
40
  >(
41
41
  options: UseQueryOptions<TQueryFnData, TError, TData, TQueryKey>,
42
42
  queryClient?: QueryClient,
43
- ) {
43
+ ): UseQueryResult<TData, TError>
44
+
45
+ export function useQuery(options: UseQueryOptions, queryClient?: QueryClient) {
44
46
  return useBaseQuery(options, QueryObserver, queryClient)
45
47
  }
@@ -0,0 +1,163 @@
1
+ 'use client'
2
+ import { useQueries } from './useQueries'
3
+ import type { UseSuspenseQueryOptions, UseSuspenseQueryResult } from './types'
4
+ import type {
5
+ DefaultError,
6
+ QueryClient,
7
+ QueryFunction,
8
+ } from '@tanstack/query-core'
9
+
10
+ // Avoid TS depth-limit error in case of large array literal
11
+ type MAXIMUM_DEPTH = 20
12
+
13
+ type GetSuspenseOptions<T> =
14
+ // Part 1: responsible for applying explicit type parameter to function arguments, if object { queryFnData: TQueryFnData, error: TError, data: TData }
15
+ T extends {
16
+ queryFnData: infer TQueryFnData
17
+ error?: infer TError
18
+ data: infer TData
19
+ }
20
+ ? UseSuspenseQueryOptions<TQueryFnData, TError, TData>
21
+ : T extends { queryFnData: infer TQueryFnData; error?: infer TError }
22
+ ? UseSuspenseQueryOptions<TQueryFnData, TError>
23
+ : T extends { data: infer TData; error?: infer TError }
24
+ ? UseSuspenseQueryOptions<unknown, TError, TData>
25
+ : // Part 2: responsible for applying explicit type parameter to function arguments, if tuple [TQueryFnData, TError, TData]
26
+ T extends [infer TQueryFnData, infer TError, infer TData]
27
+ ? UseSuspenseQueryOptions<TQueryFnData, TError, TData>
28
+ : T extends [infer TQueryFnData, infer TError]
29
+ ? UseSuspenseQueryOptions<TQueryFnData, TError>
30
+ : T extends [infer TQueryFnData]
31
+ ? UseSuspenseQueryOptions<TQueryFnData>
32
+ : // Part 3: responsible for inferring and enforcing type if no explicit parameter was provided
33
+ T extends {
34
+ queryFn?: QueryFunction<infer TQueryFnData, infer TQueryKey>
35
+ select: (data: any) => infer TData
36
+ }
37
+ ? UseSuspenseQueryOptions<TQueryFnData, Error, TData, TQueryKey>
38
+ : T extends { queryFn?: QueryFunction<infer TQueryFnData, infer TQueryKey> }
39
+ ? UseSuspenseQueryOptions<TQueryFnData, Error, TQueryFnData, TQueryKey>
40
+ : // Fallback
41
+ UseSuspenseQueryOptions
42
+
43
+ type GetSuspenseResults<T> =
44
+ // Part 1: responsible for mapping explicit type parameter to function result, if object
45
+ T extends { queryFnData: any; error?: infer TError; data: infer TData }
46
+ ? UseSuspenseQueryResult<TData, TError>
47
+ : T extends { queryFnData: infer TQueryFnData; error?: infer TError }
48
+ ? UseSuspenseQueryResult<TQueryFnData, TError>
49
+ : T extends { data: infer TData; error?: infer TError }
50
+ ? UseSuspenseQueryResult<TData, TError>
51
+ : // Part 2: responsible for mapping explicit type parameter to function result, if tuple
52
+ T extends [any, infer TError, infer TData]
53
+ ? UseSuspenseQueryResult<TData, TError>
54
+ : T extends [infer TQueryFnData, infer TError]
55
+ ? UseSuspenseQueryResult<TQueryFnData, TError>
56
+ : T extends [infer TQueryFnData]
57
+ ? UseSuspenseQueryResult<TQueryFnData>
58
+ : // Part 3: responsible for mapping inferred type to results, if no explicit parameter was provided
59
+ T extends {
60
+ queryFn?: QueryFunction<unknown, any>
61
+ select: (data: any) => infer TData
62
+ }
63
+ ? UseSuspenseQueryResult<TData>
64
+ : T extends { queryFn?: QueryFunction<infer TQueryFnData, any> }
65
+ ? UseSuspenseQueryResult<TQueryFnData>
66
+ : // Fallback
67
+ UseSuspenseQueryResult
68
+
69
+ /**
70
+ * SuspenseQueriesOptions reducer recursively unwraps function arguments to infer/enforce type param
71
+ */
72
+ export type SuspenseQueriesOptions<
73
+ T extends Array<any>,
74
+ Result extends Array<any> = [],
75
+ Depth extends ReadonlyArray<number> = [],
76
+ > = Depth['length'] extends MAXIMUM_DEPTH
77
+ ? Array<UseSuspenseQueryOptions>
78
+ : T extends []
79
+ ? []
80
+ : T extends [infer Head]
81
+ ? [...Result, GetSuspenseOptions<Head>]
82
+ : T extends [infer Head, ...infer Tail]
83
+ ? SuspenseQueriesOptions<
84
+ [...Tail],
85
+ [...Result, GetSuspenseOptions<Head>],
86
+ [...Depth, 1]
87
+ >
88
+ : Array<unknown> extends T
89
+ ? T
90
+ : // If T is *some* array but we couldn't assign unknown[] to it, then it must hold some known/homogenous type!
91
+ // use this to infer the param types in the case of Array.map() argument
92
+ T extends Array<
93
+ UseSuspenseQueryOptions<
94
+ infer TQueryFnData,
95
+ infer TError,
96
+ infer TData,
97
+ infer TQueryKey
98
+ >
99
+ >
100
+ ? Array<UseSuspenseQueryOptions<TQueryFnData, TError, TData, TQueryKey>>
101
+ : // Fallback
102
+ Array<UseSuspenseQueryOptions>
103
+
104
+ /**
105
+ * SuspenseQueriesResults reducer recursively maps type param to results
106
+ */
107
+ export type SuspenseQueriesResults<
108
+ T extends Array<any>,
109
+ Result extends Array<any> = [],
110
+ Depth extends ReadonlyArray<number> = [],
111
+ > = Depth['length'] extends MAXIMUM_DEPTH
112
+ ? Array<UseSuspenseQueryResult>
113
+ : T extends []
114
+ ? []
115
+ : T extends [infer Head]
116
+ ? [...Result, GetSuspenseResults<Head>]
117
+ : T extends [infer Head, ...infer Tail]
118
+ ? SuspenseQueriesResults<
119
+ [...Tail],
120
+ [...Result, GetSuspenseResults<Head>],
121
+ [...Depth, 1]
122
+ >
123
+ : T extends Array<
124
+ UseSuspenseQueryOptions<
125
+ infer TQueryFnData,
126
+ infer TError,
127
+ infer TData,
128
+ any
129
+ >
130
+ >
131
+ ? // Dynamic-size (homogenous) UseQueryOptions array: map directly to array of results
132
+ Array<
133
+ UseSuspenseQueryResult<
134
+ unknown extends TData ? TQueryFnData : TData,
135
+ unknown extends TError ? DefaultError : TError
136
+ >
137
+ >
138
+ : // Fallback
139
+ Array<UseSuspenseQueryResult>
140
+
141
+ export function useSuspenseQueries<
142
+ T extends Array<any>,
143
+ TCombinedResult = SuspenseQueriesResults<T>,
144
+ >(
145
+ options: {
146
+ queries: readonly [...SuspenseQueriesOptions<T>]
147
+ combine?: (result: SuspenseQueriesResults<T>) => TCombinedResult
148
+ },
149
+ queryClient?: QueryClient,
150
+ ): TCombinedResult {
151
+ return useQueries(
152
+ {
153
+ ...options,
154
+ queries: options.queries.map((query) => ({
155
+ ...query,
156
+ suspense: true,
157
+ throwOnError: true,
158
+ enabled: true,
159
+ })),
160
+ } as any,
161
+ queryClient,
162
+ )
163
+ }
package/src/utils.ts CHANGED
@@ -1,4 +1,4 @@
1
- export function shouldThrowError<T extends (...args: any[]) => boolean>(
1
+ export function shouldThrowError<T extends (...args: Array<any>) => boolean>(
2
2
  throwError: boolean | T | undefined,
3
3
  params: Parameters<T>,
4
4
  ): boolean {