Skip to content

Commit 489af0b

Browse files
fix(types): fix middleware union type merging in MergeMiddlewareResponse (#4602)
* fix(types): fix middleware union type merging in MergeMiddlewareResponse * ci: apply automated fixes * specify `fetch` as app.request --------- Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
1 parent 6ca01ec commit 489af0b

2 files changed

Lines changed: 30 additions & 4 deletions

File tree

src/types.test.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2849,6 +2849,30 @@ describe('RPC supports Middleware responses', () => {
28492849
})
28502850
})
28512851

2852+
describe('Middleware returning union type (undefined | TypedResponse)', () => {
2853+
test('middleware that conditionally returns response should merge types', async () => {
2854+
const middleware = createMiddleware(async (c, next) => {
2855+
if (Math.random() > 0.5) {
2856+
return c.json({ cause: 'Unauthorized' }, 401)
2857+
}
2858+
await next()
2859+
})
2860+
2861+
const app = new Hono().get('/test', middleware, (c) => c.json({ message: 'Hello' }, 200))
2862+
const client = hc<typeof app>('http://localhost', {
2863+
fetch: app.request,
2864+
})
2865+
const res = await client.test.$get()
2866+
2867+
if (res.status === 200) {
2868+
expectTypeOf(await res.json()).toEqualTypeOf<{ message: string }>()
2869+
}
2870+
if (res.status === 401) {
2871+
expectTypeOf(await res.json()).toEqualTypeOf<{ cause: string }>()
2872+
}
2873+
})
2874+
})
2875+
28522876
describe('Merge responses from multiple handlers, no path pattern', () => {
28532877
test('merge responses from 1 middleware', async () => {
28542878
const middleware = createMiddleware(async (c) => c.json({ '400': true }, 400))

src/types.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2368,15 +2368,17 @@ type MergeTypedResponse<T> =
23682368
? T
23692369
: TypedResponse
23702370

2371+
type ExtractTypedResponseOnly<T> = T extends TypedResponse ? T : never
2372+
23712373
type MergeMiddlewareResponse<T> = T extends (c: any, next: any) => Promise<infer R>
23722374
? Exclude<R, void> extends never
23732375
? never
2374-
: Exclude<R, void> extends TypedResponse
2375-
? Exclude<R, void>
2376+
: Exclude<R, void> extends Response | TypedResponse<any, any, any>
2377+
? ExtractTypedResponseOnly<Exclude<R, void>>
23762378
: never
23772379
: T extends (c: any, next: any) => infer R
2378-
? R extends TypedResponse
2379-
? R
2380+
? R extends Response | TypedResponse<any, any, any>
2381+
? ExtractTypedResponseOnly<R>
23802382
: never
23812383
: never
23822384

0 commit comments

Comments
 (0)