-
Notifications
You must be signed in to change notification settings - Fork 6
Description
Hello!
I have a repo demonstating the issue described below available here: https://github.com/alanbacon/zod-and-json-schema/tree/main
I have a use case for schemas with discriminated unions. As far as I understand it that means I can use the oneOf field in my JSON schema to define this:
export const apiDiscriminatedPostNodeSchema = {
type: 'object',
required: ['nodeType', 'parentNodeId'],
properties: {
// Common properties defined ONCE at the top level
parentNodeId: {
type: 'string',
},
value: {
type: 'string',
},
},
oneOf: [
{
// QUESTION Node - only discriminator and variant-specific properties
properties: {
nodeType: { const: 'QUESTION' },
nodeSpecifics: {
type: 'object',
properties: {
questionName: {
type: ['string', 'null'],
},
},
unevaluatedProperties: false,
},
},
},
{
// DECISION Node
properties: {
nodeType: { const: 'DECISION' },
nodeSpecifics: {
type: 'object',
properties: {
notes: { type: ['string', 'null'] },
},
unevaluatedProperties: false,
},
},
},
],
unevaluatedProperties: false,
} as const;the above should allow for an input object that looks like this:
const input = {
parentNodeId: '123',
value: '456',
nodeType: 'QUESTION', // the type here defines what's allowed in the nodeSpecifics, and in this case they match
nodeSpecifics: {
questionName: 'What is your name?',
}
}or this:
const input = {
parentNodeId: '123',
value: '456',
nodeType: 'DECISION', // the type here defines what's allowed in the nodeSpecifics, and in this case they match
nodeSpecifics: {
notes: 'some notes',
}
}to pass validation, but if the nodeType doesn't match the nodeSpecifics like in the below examples then the validation should fail:
const input = {
parentNodeId: '123',
value: '456',
nodeType: 'DECISION', // the type here defines what's allowed in the nodeSpecifics, and in this case they do not match
nodeSpecifics: {
questionName: 'What is your name?',
}
}or
const input = {
parentNodeId: '123',
value: '456',
nodeType: 'QUESTION', // the type here defines what's allowed in the nodeSpecifics, and in this case they do not match
nodeSpecifics: {
notes: 'some notes',
}
}Also rather strangly: if the nodeType field is completly invalid the validation also still passes when it should not.
const input = {
parentNodeId: '123',
value: '456',
nodeType: 'INVALID', // the type here defines what's allowed in the nodeSpecifics, the node type is completely invalid
nodeSpecifics: {
notes: 'some notes',
}
}Could you please take a look and let me know if im doing something incorrectly, or if there is some kind of work around.
Thanks
P.S
I also have a secondary question regarding the output type of the schema created by the convertJsonSchemaToZod function:
It appears to me that I need to cast the input JSON schema to type any in order for the convertJsonSchemaToZod to accept the type of the argument.
This results in a zod schema of type z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>. Wheras it would great if the types were a little tighter than this.