Open
Description
Consider the following example.
import { z } from 'zod'
import { zodToJsonSchema } from 'zod-to-json-schema'
export const schemaA = z.union([z.string(), z.object({})])
export const schemaB = z.object({
a: schemaA.describe('description'),
})
const jsonSchema = zodToJsonSchema(schemaB, {
definitions: { schemaA },
})
console.log(JSON.stringify(jsonSchema, null, 2))
The output of the program is the following JSON schema.
{
"type": "object",
"properties": {
"a": {
"anyOf": [
{
"$ref": "#/definitions/schemaA/anyOf/0"
},
{
"$ref": "#/definitions/schemaA/anyOf/1"
}
],
"description": "description"
}
},
"required": [
"a"
],
"additionalProperties": false,
"definitions": {
"schemaA": {
"anyOf": [
{
"type": "string"
},
{
"type": "object",
"properties": {},
"additionalProperties": false
}
]
}
},
"$schema": "http://json-schema.org/draft-07/schema#"
}
In this schema, properties.a.anyOf
unnecessarily expands each of the conditions from definitions.schemaA.anyOf
.
However if the example is slightly modified to add .optional()
, the problem goes away.
import { z } from 'zod'
import { zodToJsonSchema } from 'zod-to-json-schema'
export const schemaA = z.union([z.string(), z.object({})])
export const schemaB = z.object({
a: schemaA.optional().describe('description'),
})
const jsonSchema = zodToJsonSchema(schemaB, {
definitions: { schemaA },
})
console.log(JSON.stringify(jsonSchema, null, 2))
{
"type": "object",
"properties": {
"a": {
"$ref": "#/definitions/schemaA",
"description": "description"
}
},
"additionalProperties": false,
"definitions": {
"schemaA": {
"anyOf": [
{
"type": "string"
},
{
"type": "object",
"properties": {},
"additionalProperties": false
}
]
}
},
"$schema": "http://json-schema.org/draft-07/schema#"
}