Skip to content

anyOf unnecessarily being expanded #159

Open
@dhruvkb

Description

@dhruvkb

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#"
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions