22 * Compile-time regression checks for helper overloads and React Query options.
33 *
44 * Focus:
5- * - fetch/prefetch overload behavior
6- * - optional variables + required selection.fields custom query overloads
7- * - default vs explicit selection result narrowing in helpers
8- * - allowed/disallowed React Query options on generated hooks
5+ * - fetch/prefetch signatures for selection-enabled queries
6+ * - optional variables flow for non-selection custom queries
7+ * - pass-through and blocked React Query options
98 */
109
1110import { QueryClient } from '@tanstack/react-query' ;
1211
1312import {
1413 fetchDatabasesQuery ,
15- fetchGetObjectAtPathQuery ,
14+ fetchStepsRequiredQuery ,
15+ fetchUserByUsernameQuery ,
1616 prefetchDatabasesQuery ,
17- prefetchGetObjectAtPathQuery ,
17+ prefetchStepsRequiredQuery ,
18+ prefetchUserByUsernameQuery ,
1819 useCurrentUserQuery ,
1920 useDatabasesQuery ,
20- useGetObjectAtPathQuery ,
2121 useSignInMutation ,
22+ useStepsRequiredQuery ,
23+ useUserByUsernameQuery ,
2224} from '../generated/hooks' ;
2325
2426type Assert < T extends true > = T ;
@@ -28,9 +30,20 @@ type NotHasKey<T, K extends PropertyKey> = K extends keyof T ? false : true;
2830function helperOverloadChecks ( ) {
2931 const queryClient = new QueryClient ( ) ;
3032
31- const defaultDatabasesFetch = fetchDatabasesQuery ( { selection : { first : 2 } } ) ;
32- type DefaultDatabaseNode = Awaited < typeof defaultDatabasesFetch > [ 'databases' ] [ 'nodes' ] [ number ] ;
33- type _defaultDatabaseFetchOmitsName = Assert < NotHasKey < DefaultDatabaseNode , 'name' > > ;
33+ const idOnlyDatabasesFetch = fetchDatabasesQuery ( {
34+ selection : {
35+ first : 2 ,
36+ fields : {
37+ id : true ,
38+ } ,
39+ } ,
40+ } ) ;
41+ type IdOnlyDatabaseNode = Awaited <
42+ typeof idOnlyDatabasesFetch
43+ > [ 'databases' ] [ 'nodes' ] [ number ] ;
44+ type _idOnlyDatabaseFetchOmitsName = Assert <
45+ NotHasKey < IdOnlyDatabaseNode , 'name' >
46+ > ;
3447
3548 const selectedDatabasesFetch = fetchDatabasesQuery ( {
3649 selection : {
@@ -48,60 +61,67 @@ function helperOverloadChecks() {
4861 } ,
4962 } ,
5063 } ) ;
51- type SelectedDatabaseNode = Awaited < typeof selectedDatabasesFetch > [ 'databases' ] [ 'nodes' ] [ number ] ;
52- type _selectedDatabaseFetchHasName = Assert < HasKey < SelectedDatabaseNode , 'name' > > ;
64+ type SelectedDatabaseNode = Awaited <
65+ typeof selectedDatabasesFetch
66+ > [ 'databases' ] [ 'nodes' ] [ number ] ;
67+ type _selectedDatabaseFetchHasName = Assert <
68+ HasKey < SelectedDatabaseNode , 'name' >
69+ > ;
5370
54- prefetchDatabasesQuery ( queryClient , { selection : { first : 2 } } ) ;
5571 prefetchDatabasesQuery ( queryClient , {
5672 selection : {
5773 first : 2 ,
5874 fields : {
5975 id : true ,
60- name : true ,
6176 } ,
6277 } ,
6378 } ) ;
6479
65- // @ts -expect-error invalid helper nested select key should be rejected
66- fetchDatabasesQuery ( { selection : { fields : { schemas : { select : { invalidField : true } } } } } ) ;
67-
68- const defaultGetObjectFetch = fetchGetObjectAtPathQuery ( { variables : undefined } ) ;
69- type DefaultGetObject = Awaited < typeof defaultGetObjectFetch > [ 'getObjectAtPath' ] ;
70- type _defaultGetObjectOmitsData = Assert < NotHasKey < DefaultGetObject , 'data' > > ;
80+ // @ts -expect-error selection.fields is required
81+ fetchDatabasesQuery ( { selection : { first : 2 } } ) ;
7182
72- const selectedGetObjectFetch = fetchGetObjectAtPathQuery ( {
73- variables : undefined ,
83+ const selectedUserByUsernameFetch = fetchUserByUsernameQuery ( {
84+ variables : { username : 'dev' } ,
7485 selection : {
7586 fields : {
7687 id : true ,
77- data : true ,
88+ username : true ,
7889 } ,
7990 } ,
8091 } ) ;
81- type SelectedGetObject = Awaited < typeof selectedGetObjectFetch > [ 'getObjectAtPath' ] ;
82- type _selectedGetObjectHasData = Assert < HasKey < SelectedGetObject , 'data' > > ;
92+ type SelectedUserByUsername = Awaited <
93+ typeof selectedUserByUsernameFetch
94+ > [ 'userByUsername' ] ;
95+ type _selectedUserByUsernameHasUsername = Assert <
96+ HasKey < SelectedUserByUsername , 'username' >
97+ > ;
8398
84- prefetchGetObjectAtPathQuery ( queryClient , { variables : undefined } ) ;
85- prefetchGetObjectAtPathQuery ( queryClient , {
86- variables : undefined ,
99+ prefetchUserByUsernameQuery ( queryClient , {
100+ variables : { username : 'dev' } ,
87101 selection : {
88102 fields : {
89103 id : true ,
90104 } ,
91105 } ,
92106 } ) ;
93107
94- // @ts -expect-error invalid custom helper select key should be rejected
95- prefetchGetObjectAtPathQuery ( queryClient , {
96- variables : undefined ,
97- selection : { fields : { invalidField : true } } ,
98- } ) ;
99-
100- // @ts -expect-error custom helper select overload requires explicit variables
101- fetchGetObjectAtPathQuery ( { selection : { fields : { id : true } } } ) ;
108+ // @ts -expect-error selection is required for selection-enabled custom query helpers
109+ fetchUserByUsernameQuery ( { variables : { username : 'dev' } } ) ;
110+ // @ts -expect-error variables are required for this custom query helper
111+ fetchUserByUsernameQuery ( { selection : { fields : { id : true } } } ) ;
102112
103- // @ts -expect-error custom helper prefetch overload requires explicit variables
104- prefetchGetObjectAtPathQuery ( queryClient , { selection : { fields : { id : true } } } ) ;
113+ // Optional variables flow for custom queries without selection support.
114+ fetchStepsRequiredQuery ( ) ;
115+ fetchStepsRequiredQuery ( { variables : { vlevel : '1' , first : 10 } } ) ;
116+ prefetchStepsRequiredQuery ( queryClient ) ;
117+ prefetchStepsRequiredQuery ( queryClient , { variables : { vlevel : '1' } } ) ;
118+ useStepsRequiredQuery ( ) ;
119+ useStepsRequiredQuery ( {
120+ variables : { vlevel : '1' } ,
121+ enabled : false ,
122+ } ) ;
123+ // @ts -expect-error selection is not available on this custom query
124+ useStepsRequiredQuery ( { selection : { fields : { id : true } } } ) ;
105125}
106126
107127function reactQueryOptionsChecks ( ) {
@@ -158,12 +178,18 @@ function reactQueryOptionsChecks() {
158178 // @ts -expect-error transformed query data should not expose connection shape
159179 transformedDatabases . data . databases ;
160180
161- const transformedCurrentUser = useCurrentUserQuery ( {
162- select : ( data ) => data . currentUser . id ,
181+ const currentUserResult = useCurrentUserQuery ( {
182+ selection : {
183+ fields : {
184+ id : true ,
185+ username : true ,
186+ } ,
187+ } ,
163188 placeholderData : ( previousData ) =>
164189 previousData ?? {
165190 currentUser : {
166191 id : 'fallback-user-id' ,
192+ username : 'fallback-user' ,
167193 } ,
168194 } ,
169195 enabled : false ,
@@ -175,27 +201,18 @@ function reactQueryOptionsChecks() {
175201 return failureCount < 2 ;
176202 } ,
177203 } ) ;
178- const transformedCurrentUserId : string | undefined = transformedCurrentUser . data ;
179- void transformedCurrentUserId ;
180- // @ts -expect-error transformed query data should not expose object shape
181- transformedCurrentUser . data . currentUser ;
204+ const currentUserId : string | undefined = currentUserResult . data ?. currentUser . id ;
205+ void currentUserId ;
182206
183- useGetObjectAtPathQuery ( {
184- variables : undefined ,
207+ useUserByUsernameQuery ( {
208+ variables : { username : 'dev' } ,
185209 selection : {
186210 fields : {
187211 id : true ,
188212 } ,
189213 } ,
190214 enabled : false ,
191215 staleTime : 5_000 ,
192- gcTime : 60_000 ,
193- placeholderData : {
194- getObjectAtPath : {
195- id : 'placeholder' ,
196- } ,
197- } ,
198- select : ( data ) => data . getObjectAtPath . id ,
199216 } ) ;
200217
201218 // @ts -expect-error unknown React Query option should be rejected
@@ -204,9 +221,9 @@ function reactQueryOptionsChecks() {
204221 // @ts -expect-error queryKey is owned by generated hooks
205222 useDatabasesQuery ( { selection : { fields : { id : true } } , queryKey : [ 'override' ] as const } ) ;
206223
207- // @ts -expect-error queryFn is owned by generated hooks
208224 useDatabasesQuery ( {
209225 selection : { fields : { id : true } } ,
226+ // @ts -expect-error queryFn is owned by generated hooks
210227 queryFn : async ( ) =>
211228 ( {
212229 databases : {
@@ -224,6 +241,14 @@ function reactQueryOptionsChecks() {
224241 selection : {
225242 fields : {
226243 clientMutationId : true ,
244+ result : {
245+ select : {
246+ accessToken : true ,
247+ isVerified : true ,
248+ totpEnabled : true ,
249+ userId : true ,
250+ } ,
251+ } ,
227252 } ,
228253 } ,
229254 retry : 1 ,
@@ -243,16 +268,16 @@ function reactQueryOptionsChecks() {
243268 void context ;
244269 } ,
245270 onSuccess : ( data , variables ) => {
246- const clientMutationId = data . signIn . clientMutationId ;
271+ const accessToken = data . signIn . result . accessToken ;
247272 const email = variables . input . email ;
248- void clientMutationId ;
273+ void accessToken ;
249274 void email ;
250275 } ,
251276 } ) ;
252277
253- // @ts -expect-error mutationFn is owned by generated hooks
254278 useSignInMutation ( {
255279 selection : { fields : { clientMutationId : true } } ,
280+ // @ts -expect-error mutationFn is owned by generated hooks
256281 mutationFn : async ( ) =>
257282 ( {
258283 signIn : {
0 commit comments