Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

create schema uses anyOf instead of allOf #2008

Open
george-haroun opened this issue Jul 1, 2024 · 5 comments
Open

create schema uses anyOf instead of allOf #2008

george-haroun opened this issue Jul 1, 2024 · 5 comments

Comments

@george-haroun
Copy link

george-haroun commented Jul 1, 2024

Hello,

Below is an example where interface could be

export type ISchema = ({ foo: string } | { bar: string }) & { baz: string };

Output is

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "anyOf": [
    {
      "additionalProperties": false,
      "properties": {
        "baz": {
          "type": "string"
        },
        "foo": {
          "type": "string"
        }
      },
      "required": [
        "baz",
        "foo"
      ],
      "type": "object"
    },
    {
      "additionalProperties": false,
      "properties": {
        "bar": {
          "type": "string"
        },
        "baz": {
          "type": "string"
        }
      },
      "required": [
        "bar",
        "baz"
      ],
      "type": "object"
    }
  ],
  "definitions": {}
}

I am wondering why not using allOf instead since it's more efficient and easier to understand especially when using any schema validation lib so output could be such as

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "allOf": [
    {
      "additionalProperties": false,
      "properties": {
        "baz": {
          "type": "string"
        }
      },
      "required": [
        "baz"
      ],
      "type": "object"
    },
    {
      "anyOf": [
        {
          "additionalProperties": false,
          "properties": {
            "foo": {
              "type": "string"
            }
          },
          "required": [
            "foo"
          ],
          "type": "object"
        },
        {
          "additionalProperties": false,
          "properties": {
            "bar": {
              "type": "string"
            }
          },
          "required": [
            "bar"
          ],
          "type": "object"
        }
      ]
    }
  ],
  "definitions": {}
}

Do you guys have any clue on how to improve this ?

Thanks

@domoritz
Copy link
Member

domoritz commented Jul 1, 2024

I can't fully recall the details right now but I remember that the semantics of ts and json schema were different so that using allOf with additional properties wasn't semantically equivalent. Try a few examples and may e you find the example I can't recall right now.

@arthurfiorette
Copy link
Collaborator

arthurfiorette commented Jul 1, 2024

That's right, also a smaller schema is better for any tool that may use it.

However, I thought using references instead of literal types should result into a usage of allOf, but that's not the case:

export type Foo = { foo: string };
export type Baz = { baz: string };
export type Bar = { bar: string };

export type ISchema = (Foo | Bar) & Baz;

results into:

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "definitions": {
    "Bar": {
      "additionalProperties": false,
      "properties": {
        "bar": {
          "type": "string"
        }
      },
      "required": [
        "bar"
      ],
      "type": "object"
    },
    "Baz": {
      "additionalProperties": false,
      "properties": {
        "baz": {
          "type": "string"
        }
      },
      "required": [
        "baz"
      ],
      "type": "object"
    },
    "Foo": {
      "additionalProperties": false,
      "properties": {
        "foo": {
          "type": "string"
        }
      },
      "required": [
        "foo"
      ],
      "type": "object"
    },
    "ISchema": {
      "anyOf": [
        {
          "additionalProperties": false,
          "properties": {
            "baz": {
              "type": "string"
            },
            "foo": {
              "type": "string"
            }
          },
          "required": [
            "baz",
            "foo"
          ],
          "type": "object"
        },
        {
          "additionalProperties": false,
          "properties": {
            "bar": {
              "type": "string"
            },
            "baz": {
              "type": "string"
            }
          },
          "required": [
            "bar",
            "baz"
          ],
          "type": "object"
        }
      ]
    }
  }
}

Is that right too, @domoritz?

@arthurfiorette
Copy link
Collaborator

Related #67, #62 and #4

@domoritz
Copy link
Member

domoritz commented Jul 1, 2024

The additional properties false with all of makes the semantics tricky.

@arthurfiorette
Copy link
Collaborator

Makes sense. Is the generated schema creating any incompatibilities?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants