Skip to content

Commit

Permalink
fix(zod-openapi): support coerce (#623)
Browse files Browse the repository at this point in the history
* fix(zod-openapi): support `coerce`

* add changeset
  • Loading branch information
yusukebe committed Jul 7, 2024
1 parent 92b4cf4 commit 834a97a
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 2 deletions.
5 changes: 5 additions & 0 deletions .changeset/thirty-waves-play.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@hono/zod-openapi': patch
---

fix: support `coerce`
15 changes: 13 additions & 2 deletions packages/zod-openapi/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import type {
Schema,
ToSchema,
TypedResponse,
ValidationTargets,
} from 'hono'
import type { MergePath, MergeSchemaPath } from 'hono/types'
import type { JSONParsed, RemoveBlankRecord } from 'hono/utils/types'
Expand Down Expand Up @@ -71,14 +72,24 @@ type RequestPart<R extends RouteConfig, Part extends string> = Part extends keyo
? R['request'][Part]
: {}

type HasUndefined<T> = undefined extends T ? true : false

type InputTypeBase<
R extends RouteConfig,
Part extends string,
Type extends string
Type extends keyof ValidationTargets
> = R['request'] extends RequestTypes
? RequestPart<R, Part> extends ZodType
? {
in: { [K in Type]: z.input<RequestPart<R, Part>> }
in: {
[K in Type]: HasUndefined<ValidationTargets[K]> extends true
? {
[K2 in keyof z.input<RequestPart<R, Part>>]?: ValidationTargets[K][K2]
}
: {
[K2 in keyof z.input<RequestPart<R, Part>>]: ValidationTargets[K][K2]
}
}
out: { [K in Type]: z.output<RequestPart<R, Part>> }
}
: {}
Expand Down
36 changes: 36 additions & 0 deletions packages/zod-openapi/test/index.test-d.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import type { Env, Hono, ToSchema } from 'hono'
import { assertType, describe, expectTypeOf, it } from 'vitest'
import { OpenAPIHono, createRoute, z } from '../src/index'
import type { ExtractSchema } from 'hono/types'
import type { Equal, Expect } from 'hono/utils/types'

describe('Types', () => {
const RequestSchema = z.object({
Expand Down Expand Up @@ -198,3 +200,37 @@ describe('Response schema includes a Date type', () => {
)
})
})

describe('coerce', () => {
it('Should not throw type errors', () => {
const routes = new OpenAPIHono().openapi(
createRoute({
method: 'get',
path: '/api/users/{id}',
request: {
params: z.object({
id: z.coerce.number().openapi({ description: 'userId', example: 1 }),
}),
},
responses: {
200: {
description: 'Get a user',
},
},
}),
(c) => {
const { id } = c.req.valid('param')
assertType<number>(id)
return c.json({ id })
}
)

type Actual = ExtractSchema<typeof routes>['/api/users/:id']['$get']['input']
type Expected = {
param: {
id: string | undefined
}
}
type verify = Expect<Equal<Expected, Actual>>
})
})

0 comments on commit 834a97a

Please sign in to comment.