Skip to content

Commit e09ad8a

Browse files
authored
Merge pull request #9 from softnetics/yu/fix/throw-on-error
Fix: queryOptions type with throwOnError
2 parents 54c7cb4 + 99e3f69 commit e09ad8a

File tree

4 files changed

+119
-67
lines changed

4 files changed

+119
-67
lines changed

.changeset/dry-shirts-divide.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@softnetics/hono-react-query": patch
3+
---
4+
5+
Fix `queryOptions` and `useQuery` type for throwOnError

src/index.spec.tsx

Lines changed: 92 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import {
22
type DefinedInitialDataOptions,
3+
type DefinedUseQueryResult,
34
type UseMutationResult,
45
type UseQueryResult,
56
} from '@tanstack/react-query'
@@ -45,7 +46,7 @@ describe('createReactQueryClient', () => {
4546
expect(client.useOptimisticUpdateQuery).toBeDefined()
4647
})
4748

48-
it('Should contain Error in Data', () => {
49+
it('should contain Error in Data when throwOnError is false', () => {
4950
const client = createReactQueryClient<BasicHonoApp>({
5051
baseUrl: 'http://localhost:3000',
5152
})
@@ -59,34 +60,60 @@ describe('createReactQueryClient', () => {
5960
},
6061
})
6162

62-
type DataAndError =
63-
typeof queryOptions extends DefinedInitialDataOptions<infer TDataAndError>
64-
? TDataAndError
65-
: never
63+
expectTypeOf<typeof queryOptions>().toEqualTypeOf<
64+
DefinedInitialDataOptions<
65+
| {
66+
data: {
67+
user: {
68+
id: string
69+
name: string
70+
}
71+
}
72+
status: 200
73+
format: 'json'
74+
}
75+
| {
76+
data: {
77+
error: string
78+
}
79+
status: 400
80+
format: 'json'
81+
},
82+
Error
83+
>
84+
>()
6685

67-
expectTypeOf<DataAndError>().toEqualTypeOf<
68-
| {
69-
data: {
70-
user: {
71-
id: string
72-
name: string
86+
const queryFn = () =>
87+
client.useQuery('/users/:id', '$get', {
88+
input: { param: { id: 'none' } },
89+
options: { throwOnError: false },
90+
})
91+
92+
expectTypeOf<ReturnType<typeof queryFn>>().toEqualTypeOf<
93+
DefinedUseQueryResult<
94+
| {
95+
data: {
96+
user: {
97+
id: string
98+
name: string
99+
}
73100
}
101+
status: 200
102+
format: 'json'
74103
}
75-
status: 200
76-
format: 'json'
77-
}
78-
| Error
79-
| HonoResponseError<
80-
{
81-
error: string
104+
| {
105+
data: {
106+
error: string
107+
}
108+
status: 400
109+
format: 'json'
82110
},
83-
400,
84-
'json'
85-
>
111+
Error
112+
>
86113
>()
87114
})
88115

89-
it("Shouldn't contain Error in Data", () => {
116+
it('should not contain Error in Data when throwOnError is true', () => {
90117
const client = createReactQueryClient<BasicHonoApp>({
91118
baseUrl: 'http://localhost:3000',
92119
})
@@ -97,31 +124,49 @@ describe('createReactQueryClient', () => {
97124
},
98125
})
99126

100-
type Result =
101-
typeof queryOptions extends DefinedInitialDataOptions<infer TData, infer TError>
102-
? { data: TData; error: TError }
103-
: never
104-
105-
expectTypeOf<Result['data']>().toEqualTypeOf<{
106-
data: {
107-
user: {
108-
id: string
109-
name: string
110-
}
111-
}
112-
status: 200
113-
format: 'json'
114-
}>()
115-
116-
expectTypeOf<Result['error']>().toEqualTypeOf<
117-
| Error
118-
| HonoResponseError<
119-
{
120-
error: string
121-
},
122-
400,
123-
'json'
124-
>
127+
expectTypeOf<typeof queryOptions>().toEqualTypeOf<
128+
DefinedInitialDataOptions<
129+
{
130+
data: {
131+
user: {
132+
id: string
133+
name: string
134+
}
135+
}
136+
status: 200
137+
format: 'json'
138+
},
139+
Error | HonoResponseError<{ error: string }, 400, 'json'>
140+
>
141+
>()
142+
143+
const queryFn = () =>
144+
client.useQuery('/users/:id', '$get', {
145+
input: { param: { id: 'none' } },
146+
options: { throwOnError: true },
147+
})
148+
149+
expectTypeOf<ReturnType<typeof queryFn>>().toEqualTypeOf<
150+
DefinedUseQueryResult<
151+
{
152+
data: {
153+
user: {
154+
id: string
155+
name: string
156+
}
157+
}
158+
status: 200
159+
format: 'json'
160+
},
161+
| Error
162+
| HonoResponseError<
163+
{
164+
error: string
165+
},
166+
400,
167+
'json'
168+
>
169+
>
125170
>()
126171
})
127172

src/index.ts

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -76,13 +76,11 @@ async function responseParser(response: Response, throwOnError?: boolean): Promi
7676
: 'body',
7777
}
7878

79-
if (response.ok) {
79+
if (response.ok || !throwOnError) {
8080
return res
81-
} else if (!throwOnError) {
82-
return new HonoResponseError(res)
83-
} else {
84-
throw new HonoResponseError(res)
8581
}
82+
83+
throw new HonoResponseError(res)
8684
}
8785

8886
function useQueryFactory<T extends Record<string, any>>(

src/types.ts

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -76,20 +76,28 @@ export type UseHonoQuery<TApp extends Record<string, any>> = <
7676
>,
7777
'queryKey' | 'queryFn'
7878
>,
79+
TOptions extends HonoPayloadOptions | undefined = HonoPayloadOptions | undefined,
7980
>(
8081
path: TPath,
8182
method: TMethod,
82-
honoPayload: HonoPayload<InferFunctionInput<TApp[TPath][TMethod]>>,
83+
honoPayload: HonoPayload<InferFunctionInput<TApp[TPath][TMethod]>, TOptions>,
8384
queryOptions?: TQueryOptions
8485
) => 'initialData' extends keyof TQueryOptions
85-
? DefinedUseQueryResult<
86-
SuccessResponse<InferFunctionReturn<TApp[TPath][TMethod]>>,
87-
ErrorResponse<InferFunctionReturn<TApp[TPath][TMethod]>> | Error
88-
>
89-
: UseQueryResult<
90-
SuccessResponse<InferFunctionReturn<TApp[TPath][TMethod]>>,
91-
ErrorResponse<InferFunctionReturn<TApp[TPath][TMethod]>> | Error
92-
>
86+
? TOptions extends { throwOnError: false }
87+
? DefinedUseQueryResult<
88+
ClientResponseParser<InferFunctionReturn<TApp[TPath][TMethod]>>,
89+
DefaultError
90+
>
91+
: DefinedUseQueryResult<
92+
SuccessResponse<InferFunctionReturn<TApp[TPath][TMethod]>>,
93+
ErrorResponse<InferFunctionReturn<TApp[TPath][TMethod]>> | Error
94+
>
95+
: TOptions extends { throwOnError: false }
96+
? UseQueryResult<ClientResponseParser<InferFunctionReturn<TApp[TPath][TMethod]>>, DefaultError>
97+
: UseQueryResult<
98+
SuccessResponse<InferFunctionReturn<TApp[TPath][TMethod]>>,
99+
ErrorResponse<InferFunctionReturn<TApp[TPath][TMethod]>> | Error
100+
>
93101

94102
export type UseHonoMutation<TApp extends Record<string, any>> = <
95103
TPath extends keyof TApp,
@@ -140,9 +148,7 @@ export type HonoQueryOptions<TApp extends Record<string, any>> = <
140148
) => 'initialData' extends keyof TQueryOptions
141149
? TOptions extends { throwOnError: false }
142150
? DefinedInitialDataOptions<
143-
| SuccessResponse<InferFunctionReturn<TApp[TPath][TMethod]>>
144-
| ErrorResponse<InferFunctionReturn<TApp[TPath][TMethod]>>
145-
| Error,
151+
ClientResponseParser<InferFunctionReturn<TApp[TPath][TMethod]>>,
146152
DefaultError
147153
>
148154
: DefinedInitialDataOptions<
@@ -151,9 +157,7 @@ export type HonoQueryOptions<TApp extends Record<string, any>> = <
151157
>
152158
: TOptions extends { throwOnError: false }
153159
? UndefinedInitialDataOptions<
154-
| SuccessResponse<InferFunctionReturn<TApp[TPath][TMethod]>>
155-
| ErrorResponse<InferFunctionReturn<TApp[TPath][TMethod]>>
156-
| Error,
160+
ClientResponseParser<InferFunctionReturn<TApp[TPath][TMethod]>>,
157161
DefaultError
158162
>
159163
: UndefinedInitialDataOptions<

0 commit comments

Comments
 (0)