Type guard with Zod
Closed this issue · 1 comments
ChristoRibeiro commented
Really nice work on next-rest @joeltg !
Quick question, what is the equivalent of that with zod
?
headers: getRequestHeaders.is,
body: getRequestBody.is,
Come from this example:
import * as t from "io-ts"
const getRequestHeaders = t.type({ accept: t.literal("application/json") })
const getRequestBody = t.void
export default makeHandler("/api/widgets/[id]", {
GET: {
headers: getRequestHeaders.is,
body: getRequestBody.is,
exec: async ({ params }) => {
// ... method implementation
return {
headers: { "content-type": "application/json" },
body: { id: params.id, isGizmo: false },
}
},
},
})
ChristoRibeiro commented
There is no built-in type guard function in zod
like io-ts
with is
.
So I made a small helper for zod
:
// zod-check.ts
import { ZodSchema } from "zod"
export function check<T>(schema: ZodSchema<T>) {
function is(data: unknown): data is T {
return schema.safeParse(data).success
}
return { is }
}
I change these lines:
+ import { check } from "./zod-check"
- headers: getRequestHeaders.is,
- body: getRequestBody.is,
+ headers: check(getRequestHeaders).is,
+ body: check(getRequestBody).is,
Now the full code that use zod
validation:
import { ZodSchema } from "zod"
import { check } from "./zod-check"
const getRequestHeaders = z.object({ accept: z.literal("application/json") })
const getRequestBody = z.void()
export default makeHandler("/api/widgets/[id]", {
GET: {
headers: check(getRequestHeaders).is,
body: check(getRequestBody).is,
exec: async ({ params }) => {
// ... method implementation
return {
headers: { "content-type": "application/json" },
body: { id: params.id, isGizmo: false },
}
},
},
})