H
Hono•2w ago
tbeseda

Types issue in zod-openapi in recent release 0.19.4 (repro attached)

Maybe I'm holding it wrong, but this minimal file reproduces the type error:
import {OpenAPIHono, createRoute, z} from '@hono/zod-openapi'

interface AppBindings { Variables: { userId: string } }

const route = createRoute({
method: 'get',
path: '/widget/{widgetId}',
request: {
params: z.object({ widgetId: z.string() }),
},
responses: {
200: {
content: {
'application/json': {
schema: z.object({ widgetId: z.string() }),
},
},
description: 'Success',
},
404: {
content: {
'application/json': {
schema: z.object({
error: z.object({
code: z.string(),
message: z.string(),
}),
}),
},
},
description: 'Not Found',
},
},
})

const app = new OpenAPIHono<AppBindings>()

app.openapi(route, async (c) => { // <-- type error
const {widgetId} = c.req.valid('param')
const userId = c.get('userId')

if (widgetId === 'not-found') {
return c.json(
{
error: {
code: 'NOT_FOUND',
message: 'Not found',
},
},
404,
)
}

return c.json({widgetId}, 200)
})
import {OpenAPIHono, createRoute, z} from '@hono/zod-openapi'

interface AppBindings { Variables: { userId: string } }

const route = createRoute({
method: 'get',
path: '/widget/{widgetId}',
request: {
params: z.object({ widgetId: z.string() }),
},
responses: {
200: {
content: {
'application/json': {
schema: z.object({ widgetId: z.string() }),
},
},
description: 'Success',
},
404: {
content: {
'application/json': {
schema: z.object({
error: z.object({
code: z.string(),
message: z.string(),
}),
}),
},
},
description: 'Not Found',
},
},
})

const app = new OpenAPIHono<AppBindings>()

app.openapi(route, async (c) => { // <-- type error
const {widgetId} = c.req.valid('param')
const userId = c.get('userId')

if (widgetId === 'not-found') {
return c.json(
{
error: {
code: 'NOT_FOUND',
message: 'Not found',
},
},
404,
)
}

return c.json({widgetId}, 200)
})
6 Replies
tbeseda
tbesedaOP•2w ago
Here's the text of the type error
Argument of type '(c: Context<AppBindings, "/widget/:widgetId", { in: { param: { widgetId?: string; }; }; out: { param: { widgetId?: string; }; }; }>) => Promise<JSONRespondReturn<{ error: { code: string; message: string; }; }, 404> | JSONRespondReturn<...>>' is not assignable to parameter of type 'Handler<AppBindings, "/widget/:widgetId", { in: { param: { widgetId?: string; }; }; out: { param: { widgetId?: string; }; }; }, Promise<never>>'.
Type 'Promise<JSONRespondReturn<{ error: { code: string; message: string; }; }, 404> | JSONRespondReturn<{ widgetId: string; }, 200>>' is not assignable to type 'Promise<never>'.
Type 'JSONRespondReturn<{ error: { code: string; message: string; }; }, 404> | JSONRespondReturn<{ widgetId: string; }, 200>' is not assignable to type 'never'.
Type 'JSONRespondReturn<{ error: { code: string; message: string; }; }, 404>' is not assignable to type 'never'.ts(2345)
Argument of type '(c: Context<AppBindings, "/widget/:widgetId", { in: { param: { widgetId?: string; }; }; out: { param: { widgetId?: string; }; }; }>) => Promise<JSONRespondReturn<{ error: { code: string; message: string; }; }, 404> | JSONRespondReturn<...>>' is not assignable to parameter of type 'Handler<AppBindings, "/widget/:widgetId", { in: { param: { widgetId?: string; }; }; out: { param: { widgetId?: string; }; }; }, Promise<never>>'.
Type 'Promise<JSONRespondReturn<{ error: { code: string; message: string; }; }, 404> | JSONRespondReturn<{ widgetId: string; }, 200>>' is not assignable to type 'Promise<never>'.
Type 'JSONRespondReturn<{ error: { code: string; message: string; }; }, 404> | JSONRespondReturn<{ widgetId: string; }, 200>' is not assignable to type 'never'.
Type 'JSONRespondReturn<{ error: { code: string; message: string; }; }, 404>' is not assignable to type 'never'.ts(2345)
tbeseda
tbesedaOP•2w ago
perhaps there's a bug in the fix for this issue šŸ¤” https://github.com/honojs/middleware/issues/1102
GitHub
Variables are of type never when there's a middleware with @hono/...
Which middleware has the bug? @hono/zod-openapi What version of the middleware? 0.19.2 What version of Hono are you using? 4.7.5 What runtime/platform is your app running on? (with version if possi...
ambergristle
ambergristle•2w ago
i can't repro on 0.19.4 have you tried restarting your ts server, and/or reinstalling dependencies?
tbeseda
tbesedaOP•3d ago
$ npm ls @hono/zod-openapi

[email protected] /Users/my-project
ā”œā”€ā”€ @hono/[email protected]
$ npm ls @hono/zod-openapi

[email protected] /Users/my-project
ā”œā”€ā”€ @hono/[email protected]
$ tsc repro.ts

repro.ts:42:20 - error TS2345: Argument of type '(c: Context<AppBindings, "/widget/:widgetId", { in: { param: { widgetId?: string; }; }; out: { param: { widgetId?: string; }; }; }>) => Promise<JSONRespondReturn<{ error: { code: string; message: string; }; }, 404> | JSONRespondReturn<...>>' is not assignable to parameter of type 'Handler<AppBindings, "/widget/:widgetId", { in: { param: { widgetId?: string; }; }; out: { param: { widgetId?: string; }; }; }, Promise<never>>'.
Type 'Promise<JSONRespondReturn<{ error: { code: string; message: string; }; }, 404> | JSONRespondReturn<{ widgetId: string; }, 200>>' is not assignable to type 'Promise<never>'.
Type 'JSONRespondReturn<{ error: { code: string; message: string; }; }, 404> | JSONRespondReturn<{ widgetId: string; }, 200>' is not assignable to type 'never'.
Type 'JSONRespondReturn<{ error: { code: string; message: string; }; }, 404>' is not assignable to type 'never'.

42 app.openapi(route, async (c) => {
~~~~~~~~~~~~~~
$ tsc repro.ts

repro.ts:42:20 - error TS2345: Argument of type '(c: Context<AppBindings, "/widget/:widgetId", { in: { param: { widgetId?: string; }; }; out: { param: { widgetId?: string; }; }; }>) => Promise<JSONRespondReturn<{ error: { code: string; message: string; }; }, 404> | JSONRespondReturn<...>>' is not assignable to parameter of type 'Handler<AppBindings, "/widget/:widgetId", { in: { param: { widgetId?: string; }; }; out: { param: { widgetId?: string; }; }; }, Promise<never>>'.
Type 'Promise<JSONRespondReturn<{ error: { code: string; message: string; }; }, 404> | JSONRespondReturn<{ widgetId: string; }, 200>>' is not assignable to type 'Promise<never>'.
Type 'JSONRespondReturn<{ error: { code: string; message: string; }; }, 404> | JSONRespondReturn<{ widgetId: string; }, 200>' is not assignable to type 'never'.
Type 'JSONRespondReturn<{ error: { code: string; message: string; }; }, 404>' is not assignable to type 'never'.

42 app.openapi(route, async (c) => {
~~~~~~~~~~~~~~
and with 0.19.2 it builds. (0.19.3 has the yarn workspace bug mentioned here - fixed in 0.19.4) (bump) I still see this issue in 0.19.5 Only way I see to fix it is using
as unknown as Promise<never>
as unknown as Promise<never>
😬
tbeseda
tbesedaOP•3d ago
got this down to a minimal reproduction sandbox on Stackblitz Run npm run typecheck to see the error (the editor doesn't immediately show the issue until the file is edited)
Taylor Beseda
StackBlitz
hono-zod-type-error - StackBlitz
A TypeScript project based on @hono/zod-openapi, @types/node and typescript
ambergristle
ambergristle•3d ago
Dope. Thanks for putting this together!

Did you find this page helpful?