11import { describe , expectTypeOf , it } from 'vitest'
2+ import { skipToken } from '@tanstack/query-core'
23import { queryKey } from '@tanstack/query-test-utils'
34import { queryOptions , useQueries } from '..'
5+ import { QueryClient } from '../QueryClient'
6+ import type { OmitKeyof } from '@tanstack/query-core'
47import type { UseQueryResult } from '..'
8+ import type { SolidQueryOptions } from '../types'
59
610describe ( 'useQueries' , ( ) => {
11+ it ( 'TData should have undefined in the union even when initialData is provided as an object' , ( ) => {
12+ const query1 = {
13+ queryKey : queryKey ( ) ,
14+ queryFn : ( ) => {
15+ return {
16+ wow : true ,
17+ }
18+ } ,
19+ initialData : {
20+ wow : false ,
21+ } ,
22+ }
23+
24+ const query2 = {
25+ queryKey : queryKey ( ) ,
26+ queryFn : ( ) => 'Query Data' ,
27+ initialData : 'initial data' ,
28+ }
29+
30+ const query3 = {
31+ queryKey : queryKey ( ) ,
32+ queryFn : ( ) => 'Query Data' ,
33+ }
34+
35+ const queryResults = useQueries ( ( ) => ( {
36+ queries : [ query1 , query2 , query3 ] ,
37+ } ) )
38+
39+ const query1Data = queryResults [ 0 ] . data
40+ const query2Data = queryResults [ 1 ] . data
41+ const query3Data = queryResults [ 2 ] . data
42+
43+ expectTypeOf ( query1Data ) . toEqualTypeOf < { wow : boolean } | undefined > ( )
44+ expectTypeOf ( query2Data ) . toEqualTypeOf < string | undefined > ( )
45+ expectTypeOf ( query3Data ) . toEqualTypeOf < string | undefined > ( )
46+ } )
47+
48+ it ( 'TData should have undefined in the union when passed through queryOptions' , ( ) => {
49+ const options = queryOptions ( {
50+ queryKey : queryKey ( ) ,
51+ queryFn : ( ) => {
52+ return {
53+ wow : true ,
54+ }
55+ } ,
56+ initialData : {
57+ wow : true ,
58+ } ,
59+ } )
60+ const queryResults = useQueries ( ( ) => ( { queries : [ options ] } ) )
61+
62+ const data = queryResults [ 0 ] . data
63+
64+ expectTypeOf ( data ) . toEqualTypeOf < { wow : boolean } | undefined > ( )
65+ } )
66+
67+ it ( 'TData should have undefined in the union when initialData is provided as a function which can return undefined' , ( ) => {
68+ const queryResults = useQueries ( ( ) => ( {
69+ queries : [
70+ {
71+ queryKey : queryKey ( ) ,
72+ queryFn : ( ) => {
73+ return {
74+ wow : true ,
75+ }
76+ } ,
77+ initialData : ( ) => undefined as { wow : boolean } | undefined ,
78+ } ,
79+ ] ,
80+ } ) )
81+
82+ const data = queryResults [ 0 ] . data
83+
84+ expectTypeOf ( data ) . toEqualTypeOf < { wow : boolean } | undefined > ( )
85+ } )
86+
87+ it ( 'should infer types from explicit object type parameter' , ( ) => {
88+ const queryResults = useQueries <
89+ [
90+ { queryFnData : number } ,
91+ { queryFnData : string ; error : Error } ,
92+ { queryFnData : boolean ; data : string } ,
93+ ]
94+ > ( ( ) => ( {
95+ queries : [
96+ {
97+ queryKey : queryKey ( ) ,
98+ queryFn : ( ) => Promise . resolve ( 1 ) ,
99+ } ,
100+ {
101+ queryKey : queryKey ( ) ,
102+ queryFn : ( ) => Promise . resolve ( 'data' ) ,
103+ } ,
104+ {
105+ queryKey : queryKey ( ) ,
106+ queryFn : ( ) => Promise . resolve ( true ) ,
107+ select : ( ) => 'selected' ,
108+ } ,
109+ ] ,
110+ } ) )
111+
112+ expectTypeOf ( queryResults [ 0 ] . data ) . toEqualTypeOf < number | undefined > ( )
113+ expectTypeOf ( queryResults [ 1 ] . data ) . toEqualTypeOf < string | undefined > ( )
114+ expectTypeOf ( queryResults [ 1 ] . error ) . toEqualTypeOf < Error | null > ( )
115+ expectTypeOf ( queryResults [ 2 ] . data ) . toEqualTypeOf < string | undefined > ( )
116+ } )
117+
118+ it ( 'should infer types from explicit tuple type parameter' , ( ) => {
119+ const queryResults = useQueries <
120+ [ [ number ] , [ string , Error ] , [ boolean , Error , string ] ]
121+ > ( ( ) => ( {
122+ queries : [
123+ {
124+ queryKey : queryKey ( ) ,
125+ queryFn : ( ) => Promise . resolve ( 1 ) ,
126+ } ,
127+ {
128+ queryKey : queryKey ( ) ,
129+ queryFn : ( ) => Promise . resolve ( 'data' ) ,
130+ } ,
131+ {
132+ queryKey : queryKey ( ) ,
133+ queryFn : ( ) => Promise . resolve ( true ) ,
134+ select : ( ) => 'selected' ,
135+ } ,
136+ ] ,
137+ } ) )
138+
139+ expectTypeOf ( queryResults [ 0 ] . data ) . toEqualTypeOf < number | undefined > ( )
140+ expectTypeOf ( queryResults [ 1 ] . data ) . toEqualTypeOf < string | undefined > ( )
141+ expectTypeOf ( queryResults [ 1 ] . error ) . toEqualTypeOf < Error | null > ( )
142+ expectTypeOf ( queryResults [ 2 ] . data ) . toEqualTypeOf < string | undefined > ( )
143+ } )
144+
145+ it ( 'should be possible to define a different TData than TQueryFnData using select with queryOptions spread into useQuery' , ( ) => {
146+ const query1 = queryOptions ( {
147+ queryKey : queryKey ( ) ,
148+ queryFn : ( ) => Promise . resolve ( 1 ) ,
149+ select : ( data ) => data > 1 ,
150+ } )
151+
152+ const query2 = {
153+ queryKey : queryKey ( ) ,
154+ queryFn : ( ) => Promise . resolve ( 1 ) ,
155+ select : ( data : number ) => data > 1 ,
156+ }
157+
158+ const queryResults = useQueries ( ( ) => ( { queries : [ query1 , query2 ] } ) )
159+ const query1Data = queryResults [ 0 ] . data
160+ const query2Data = queryResults [ 1 ] . data
161+
162+ expectTypeOf ( query1Data ) . toEqualTypeOf < boolean | undefined > ( )
163+ expectTypeOf ( query2Data ) . toEqualTypeOf < boolean | undefined > ( )
164+ } )
165+
166+ describe ( 'custom hook' , ( ) => {
167+ it ( 'should allow custom hooks using SolidQueryOptions' , ( ) => {
168+ type Data = string
169+
170+ const useCustomQueries = (
171+ options ?: OmitKeyof < SolidQueryOptions < Data > , 'queryKey' | 'queryFn' > ,
172+ ) => {
173+ return useQueries ( ( ) => ( {
174+ queries : [
175+ {
176+ ...options ,
177+ queryKey : queryKey ( ) ,
178+ queryFn : ( ) => Promise . resolve ( 'data' ) ,
179+ } ,
180+ ] ,
181+ } ) )
182+ }
183+
184+ const queryResults = useCustomQueries ( )
185+ const data = queryResults [ 0 ] . data
186+
187+ expectTypeOf ( data ) . toEqualTypeOf < Data | undefined > ( )
188+ } )
189+ } )
190+
191+ it ( 'should infer custom TError from throwOnError' , ( ) => {
192+ class CustomError extends Error {
193+ code : number
194+ constructor ( code : number ) {
195+ super ( )
196+ this . code = code
197+ }
198+ }
199+
200+ const queryResults = useQueries ( ( ) => ( {
201+ queries : [
202+ {
203+ queryKey : queryKey ( ) ,
204+ queryFn : ( ) => Promise . resolve ( 'data' ) ,
205+ throwOnError : ( _error : CustomError ) => false ,
206+ } ,
207+ ] ,
208+ } ) )
209+
210+ expectTypeOf ( queryResults [ 0 ] . error ) . toEqualTypeOf < CustomError | null > ( )
211+ } )
212+
213+ it ( 'TData should have correct type when conditional skipToken is passed' , ( ) => {
214+ const queryResults = useQueries ( ( ) => ( {
215+ queries : [
216+ {
217+ queryKey : queryKey ( ) ,
218+ queryFn : Math . random ( ) > 0.5 ? skipToken : ( ) => Promise . resolve ( 5 ) ,
219+ } ,
220+ ] ,
221+ } ) )
222+
223+ const firstResult = queryResults [ 0 ]
224+
225+ expectTypeOf ( firstResult ) . toEqualTypeOf < UseQueryResult < number , Error > > ( )
226+ expectTypeOf ( firstResult . data ) . toEqualTypeOf < number | undefined > ( )
227+ } )
228+
7229 it ( 'should return correct data for dynamic queries with mixed result types' , ( ) => {
8230 const Queries1 = {
9231 get : ( ) =>
@@ -29,4 +251,42 @@ describe('useQueries', () => {
29251 [ ...Array < UseQueryResult < number , Error > > , UseQueryResult < boolean , Error > ]
30252 > ( )
31253 } )
254+
255+ it ( 'should accept queryClient as second argument' , ( ) => {
256+ const queryClient = new QueryClient ( )
257+
258+ const queryResults = useQueries (
259+ ( ) => ( {
260+ queries : [
261+ {
262+ queryKey : queryKey ( ) ,
263+ queryFn : ( ) => Promise . resolve ( 'data' ) ,
264+ } ,
265+ ] ,
266+ } ) ,
267+ ( ) => queryClient ,
268+ )
269+
270+ expectTypeOf ( queryResults [ 0 ] . data ) . toEqualTypeOf < string | undefined > ( )
271+ } )
272+
273+ it ( 'should infer correct types for combine callback parameter' , ( ) => {
274+ useQueries ( ( ) => ( {
275+ queries : [
276+ {
277+ queryKey : queryKey ( ) ,
278+ queryFn : ( ) => Promise . resolve ( 1 ) ,
279+ } ,
280+ {
281+ queryKey : queryKey ( ) ,
282+ queryFn : ( ) => Promise . resolve ( 'hello' ) ,
283+ } ,
284+ ] ,
285+ combine : ( results ) => {
286+ expectTypeOf ( results [ 0 ] ) . toEqualTypeOf < UseQueryResult < number , Error > > ( )
287+ expectTypeOf ( results [ 1 ] ) . toEqualTypeOf < UseQueryResult < string , Error > > ( )
288+ return results
289+ } ,
290+ } ) )
291+ } )
32292} )
0 commit comments