@@ -7,61 +7,35 @@ import {
7
7
type UseSuspenseQueryResult ,
8
8
type QueryClient ,
9
9
type QueryFunctionContext ,
10
+ type DataTag ,
10
11
useMutation ,
11
12
useQuery ,
12
- useSuspenseQuery ,
13
- queryOptions ,
13
+ useSuspenseQuery ,
14
+ dataTagSymbol ,
14
15
} from "@tanstack/react-query" ;
15
16
import type { ClientMethod , FetchResponse , MaybeOptionalInit , Client as FetchClient } from "openapi-fetch" ;
16
17
import type { HttpMethod , MediaType , PathsWithMethod , RequiredKeysOf } from "openapi-typescript-helpers" ;
17
18
18
19
type InitWithUnknowns < Init > = Init & { [ key : string ] : unknown } ;
19
20
20
- // biome-ignore lint/suspicious/noRedeclare: <https://stackoverflow.com/questions/52760509/typescript-returntype-of-overloaded-function>
21
- type OverloadedReturnType < T > = T extends { ( ...args : any [ ] ) : infer R ; ( ...args : any [ ] ) : infer R }
22
- ? R
23
- : T extends ( ...args : any [ ] ) => infer R
24
- ? R
25
- : any ;
26
-
27
- type OverloadedParameters < T > = T extends { ( ...args : infer P1 ) : any ; ( ...args : infer P2 ) : any }
28
- ? P1
29
- : T extends ( ...args : infer P ) => any
30
- ? P
31
- : never ;
32
-
33
21
export type QueryKey <
34
22
Paths extends Record < string , Record < HttpMethod , { } > > ,
35
23
Method extends HttpMethod ,
36
24
Path extends PathsWithMethod < Paths , Method > ,
37
- > = readonly [ Method , Path , MaybeOptionalInit < Paths [ Path ] , Method > ] ;
38
-
39
- export type QueryOptionsFunction < Paths extends Record < string , Record < HttpMethod , { } > > , Media extends MediaType > = <
40
- Method extends HttpMethod ,
41
- Path extends PathsWithMethod < Paths , Method > ,
42
- Init extends MaybeOptionalInit < Paths [ Path ] , Method > ,
43
- Response extends Required < FetchResponse < Paths [ Path ] [ Method ] , Init , Media > > , // note: Required is used to avoid repeating NonNullable in UseQuery types
44
- Options extends Omit <
45
- UseQueryOptions < Response [ "data" ] , Response [ "error" ] , Response [ "data" ] , QueryKey < Paths , Method , Path > > ,
46
- "queryKey" | "queryFn"
25
+ Media extends MediaType ,
26
+ Init extends MaybeOptionalInit < Paths [ Path ] , Method > = MaybeOptionalInit < Paths [ Path ] , Method > ,
27
+ Response extends Required < FetchResponse < Paths [ Path ] [ Method ] , Init , Media > > = Required <
28
+ FetchResponse < Paths [ Path ] [ Method ] , Init , Media >
47
29
> ,
48
- > (
49
- method : Method ,
50
- path : Path ,
51
- ...[ init , options ] : RequiredKeysOf < Init > extends never
52
- ? [ InitWithUnknowns < Init > ?, Options ?]
53
- : [ InitWithUnknowns < Init > , Options ?]
54
- ) => UseQueryOptions < Response [ "data" ] , Response [ "error" ] , Response [ "data" ] , QueryKey < Paths , Method , Path > > ;
30
+ > = DataTag < readonly [ Method , Path , Init ] , Response [ "data" ] > ;
55
31
56
- export type QueryOptionsObject < Paths extends Record < string , Record < HttpMethod , { } > > , Media extends MediaType > = <
32
+ export type QueryOptionsFunction < Paths extends Record < string , Record < HttpMethod , { } > > , Media extends MediaType > = <
57
33
Method extends HttpMethod ,
58
34
Path extends PathsWithMethod < Paths , Method > ,
59
35
Init extends MaybeOptionalInit < Paths [ Path ] , Method > ,
60
36
Response extends Required < FetchResponse < Paths [ Path ] [ Method ] , Init , Media > > , // note: Required is used to avoid repeating NonNullable in UseQuery types
61
37
Options extends Omit <
62
- OverloadedParameters <
63
- typeof queryOptions < Response [ "data" ] , Response [ "error" ] , Response [ "data" ] , QueryKey < Paths , Method , Path > >
64
- > [ 0 ] ,
38
+ UseQueryOptions < Response [ "data" ] , Response [ "error" ] , Response [ "data" ] , QueryKey < Paths , Method , Path , Media > > ,
65
39
"queryKey" | "queryFn"
66
40
> ,
67
41
> (
@@ -70,17 +44,15 @@ export type QueryOptionsObject<Paths extends Record<string, Record<HttpMethod, {
70
44
...[ init , options ] : RequiredKeysOf < Init > extends never
71
45
? [ InitWithUnknowns < Init > ?, Options ?]
72
46
: [ InitWithUnknowns < Init > , Options ?]
73
- ) => OverloadedReturnType <
74
- typeof queryOptions < Response [ "data" ] , Response [ "error" ] , Response [ "data" ] , QueryKey < Paths , Method , Path > >
75
- > ;
47
+ ) => UseQueryOptions < Response [ "data" ] , Response [ "error" ] , Response [ "data" ] , QueryKey < Paths , Method , Path , Media > > ;
76
48
77
49
export type UseQueryMethod < Paths extends Record < string , Record < HttpMethod , { } > > , Media extends MediaType > = <
78
50
Method extends HttpMethod ,
79
51
Path extends PathsWithMethod < Paths , Method > ,
80
52
Init extends MaybeOptionalInit < Paths [ Path ] , Method > ,
81
53
Response extends Required < FetchResponse < Paths [ Path ] [ Method ] , Init , Media > > , // note: Required is used to avoid repeating NonNullable in UseQuery types
82
54
Options extends Omit <
83
- UseQueryOptions < Response [ "data" ] , Response [ "error" ] , Response [ "data" ] , QueryKey < Paths , Method , Path > > ,
55
+ UseQueryOptions < Response [ "data" ] , Response [ "error" ] , Response [ "data" ] , QueryKey < Paths , Method , Path , Media > > ,
84
56
"queryKey" | "queryFn"
85
57
> ,
86
58
> (
@@ -97,7 +69,12 @@ export type UseSuspenseQueryMethod<Paths extends Record<string, Record<HttpMetho
97
69
Init extends MaybeOptionalInit < Paths [ Path ] , Method > ,
98
70
Response extends Required < FetchResponse < Paths [ Path ] [ Method ] , Init , Media > > , // note: Required is used to avoid repeating NonNullable in UseQuery types
99
71
Options extends Omit <
100
- UseSuspenseQueryOptions < Response [ "data" ] , Response [ "error" ] , Response [ "data" ] , QueryKey < Paths , Method , Path > > ,
72
+ UseSuspenseQueryOptions <
73
+ Response [ "data" ] ,
74
+ Response [ "error" ] ,
75
+ Response [ "data" ] ,
76
+ QueryKey < Paths , Method , Path , Media >
77
+ > ,
101
78
"queryKey" | "queryFn"
102
79
> ,
103
80
> (
@@ -122,7 +99,7 @@ export type UseMutationMethod<Paths extends Record<string, Record<HttpMethod, {}
122
99
) => UseMutationResult < Response [ "data" ] , Response [ "error" ] , Init > ;
123
100
124
101
export interface OpenapiQueryClient < Paths extends { } , Media extends MediaType = MediaType > {
125
- queryOptions : QueryOptionsObject < Paths , Media > ;
102
+ queryOptions : QueryOptionsFunction < Paths , Media > ;
126
103
useQuery : UseQueryMethod < Paths , Media > ;
127
104
useSuspenseQuery : UseSuspenseQueryMethod < Paths , Media > ;
128
105
useMutation : UseMutationMethod < Paths , Media > ;
@@ -135,7 +112,7 @@ export default function createClient<Paths extends {}, Media extends MediaType =
135
112
const queryFn = async < Method extends HttpMethod , Path extends PathsWithMethod < Paths , Method > > ( {
136
113
queryKey : [ method , path , init ] ,
137
114
signal,
138
- } : QueryFunctionContext < QueryKey < Paths , Method , Path > > ) => {
115
+ } : QueryFunctionContext < QueryKey < Paths , Method , Path , Media > > ) => {
139
116
const mth = method . toUpperCase ( ) as Uppercase < typeof method > ;
140
117
const fn = client [ mth ] as ClientMethod < Paths , typeof method , Media > ;
141
118
const { data, error } = await fn ( path , { signal, ...( init as any ) } ) ; // TODO: find a way to avoid as any
@@ -145,24 +122,22 @@ export default function createClient<Paths extends {}, Media extends MediaType =
145
122
return data ;
146
123
} ;
147
124
148
- const queryOptionsParams : QueryOptionsFunction < Paths , Media > = ( method , path , ...[ init , options ] ) => ( {
149
- queryKey : [ method , path , init as InitWithUnknowns < typeof init > ] as const ,
150
- queryFn,
151
- ...options ,
152
- } ) ;
125
+ const queryOptions : QueryOptionsFunction < Paths , Media > = ( method , path , ...[ init , options ] ) => {
126
+ return {
127
+ queryKey : Object . assign ( [ method , path , init as InitWithUnknowns < typeof init > ] as const , {
128
+ [ dataTagSymbol ] : { } as any ,
129
+ } ) ,
130
+ queryFn,
131
+ ...options ,
132
+ } ;
133
+ } ;
153
134
154
135
return {
155
- queryOptions : ( method , path , ...[ init , options ] ) =>
156
- queryOptions ( {
157
- queryKey : [ method , path , init as InitWithUnknowns < typeof init > ] as const ,
158
- queryFn,
159
- // TODO: find a way to avoid as any
160
- ...( options as any ) ,
161
- } ) ,
136
+ queryOptions,
162
137
useQuery : ( method , path , ...[ init , options , queryClient ] ) =>
163
- useQuery ( queryOptionsParams ( method , path , init as InitWithUnknowns < typeof init > , options ) , queryClient ) ,
138
+ useQuery ( queryOptions ( method , path , init as InitWithUnknowns < typeof init > , options ) , queryClient ) ,
164
139
useSuspenseQuery : ( method , path , ...[ init , options , queryClient ] ) =>
165
- useSuspenseQuery ( queryOptionsParams ( method , path , init as InitWithUnknowns < typeof init > , options ) , queryClient ) ,
140
+ useSuspenseQuery ( queryOptions ( method , path , init as InitWithUnknowns < typeof init > , options ) , queryClient ) ,
166
141
useMutation : ( method , path , options , queryClient ) =>
167
142
useMutation (
168
143
{
0 commit comments