(zod-openapi) Return type of `handler` doesn't respect the schema strictness
Hi, I'm having a problem making sure the return type of a handler to be as strict as the defined zod schema in createRoute. Consider the following code:
const app = new OpenAPIHono().openapi(
createRoute({
summary: 'Test route',
method: 'post',
path: '/test',
responses: {
200: {
description: 'test',
content: {
'application/json': {
schema: z
.object({
name: z.string(),
})
.strict(), // <= a supposedly strict schema for { name: string; }
},
},
},
},
}),
(c) => {
return c.jsonT({
name: 'John Doe',
});
}
);
However, it seems that zod-openapi doesn't do a type parse/validation on return type. The following handler which returns an extra property/key also works, and doesn't throw an error:
(c) => {
return c.jsonT({
name: 'John Doe',
+ age: 12,
});
}
This could make the API less safe/secure. For example after fetching user data from a DB table, the developer could accidentally return the user data without omitting the password fields first, because TypeScript doesn't complain about the extra "password" field.
I think this is related to the usage of z.infer in the OutputType<R> type, which I guess can be fixed by either:
- raising a runtime error (i.e. invoking a
z.parse()on the response) (using an extra middleware?) - or using advanced TypeScript typechecking tricks
Is there a workaround for making sure the type is exactly the same? Or is there something I'm missing? Anyway thank you for the amazing works!
Hi! @masnormen
You are correct, Hono's Validator does not validate the response. What Zod OpenAPI does now is very loose validation. I would like to think about this issue. Thanks.
Hi. I've found a solution for this issue and would like to propose a PR soon. Thanks for the response!
Great! Waiting!
@masnormen what was your solution?