-
Notifications
You must be signed in to change notification settings - Fork 71
Description
To Reproduce
`it('should handle "oneOf" for unions using a superRefine', () => {
const jsonSchema: JsonSchema = {
oneOf: [
{ type: 'object', properties: { email: { type: 'string' } } },
{ type: 'object', properties: { phone: { type: 'string' } } },
],
};
const zodSchemaString = jsonSchemaToZod(jsonSchema, { module: 'none' });
const Schema = (function(z) {
return eval(zodSchemaString);
})(z);
expect(() => Schema.parse({ email: 'test@example.com' })).not.toThrow();
expect(() => Schema.parse({ phone: '555-1234' })).not.toThrow();
expect(() => Schema.strict().parse({ email: 'test@example.com', phone: '555-1234' })).toThrow(); // does not throw
});`
This test fails on the last expect as the outputted schema is
"z.any().superRefine((x, ctx) => { const schemas = [z.object({ \"email\": z.string().optional() }), z.object({ \"phone\": z.string().optional() })]; const errors = schemas.reduce<z.ZodError[]>( (errors, schema) => ((result) => result.error ? [...errors, result.error] : errors)( schema.safeParse(x), ), [], ); if (schemas.length - errors.length !== 1) { ctx.addIssue({ path: ctx.path, code: \"invalid_union\", unionErrors: errors, message: \"Invalid input: Should pass single schema\", }); } })
Which does not have a check for exactly one field.
I believe it would be better to use z.union than z.any in this case. Happy to take a look at a potential PR fix