vega / ts-json-schema-generator

Generate JSON schema from your Typescript sources
MIT License
1.44k stars 190 forks source link

Support for `Pick`, `Exclude` and `Omit` typescript type helpers. #993

Open bertrand-caron opened 2 years ago

bertrand-caron commented 2 years ago

Hi,

I have the following example which seems to return erroneous results:

export type A = {
    readonly a1: string
    readonly a2: string
}

export type B1 = A & {
    readonly b1: string
}

export type B2 = A & {
    readonly b2: string
}

export type B = B1 | B2

export type C = Omit<B, 'a2'> 

The JSON schema for type C should be a type union, but is not:

$ yarn run --silent ts-json-schema-generator --path test.ts --type C
{
  "$ref": "#/definitions/C",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "definitions": {
    "C": {
      "additionalProperties": false,
      "properties": {
        "a1": {
          "type": "string"
        },
        "b1": {
          "type": "string"
        },
        "b2": {
          "type": "string"
        }
      },
      "required": [
        "a1",
        "b1",
        "b2"
      ],
      "type": "object"
    }
  }
}

Note that the type B seems to be correctly handled:

$ yarn run --silent ts-json-schema-generator --path A.ts --type B   
{
  "$ref": "#/definitions/B",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "definitions": {
    "B": {
      "anyOf": [
        {
          "$ref": "#/definitions/B1"
        },
        {
          "$ref": "#/definitions/B2"
        }
      ]
    },
    "B1": {
      "additionalProperties": false,
      "properties": {
        "a1": {
          "type": "string"
        },
        "a2": {
          "type": "string"
        },
        "b1": {
          "type": "string"
        }
      },
      "required": [
        "a1",
        "a2",
        "b1"
      ],
      "type": "object"
    },
    "B2": {
      "additionalProperties": false,
      "properties": {
        "a1": {
          "type": "string"
        },
        "a2": {
          "type": "string"
        },
        "b2": {
          "type": "string"
        }
      },
      "required": [
        "a1",
        "a2",
        "b2"
      ],
      "type": "object"
    }
  }
}

Note that I am running "ts-json-schema-generator": "0.96.0" and "typescript": "4.3.5".

bertrand-caron commented 2 years ago

Note that I was previously using typescript-json-schema which handled this well (but not other things :S), in case that helps narrow down the issue.

domoritz commented 2 years ago

Thanks for filing the issue. You might be able to narrow down the issue a bit more. Then, you could look into the corresponding code to see what may cause this bug.

bertrand-caron commented 2 years ago

Hi @domoritz , thanks a lot for the quick response :)

Is there anything more that you would like me to provide? I feel like my example is minimal, well-defined and self-contained.

Just for completeness, this is the expected schema (same as B, but with the property a2 omitted from both B1 and B2):

$ yarn run --silent ts-json-schema-generator --path A.ts --type C   
{
  "$ref": "#/definitions/B",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "definitions": {
    "B": {
      "anyOf": [
        {
          "$ref": "#/definitions/B1"
        },
        {
          "$ref": "#/definitions/B2"
        }
      ]
    },
    "B1": {
      "additionalProperties": false,
      "properties": {
        "a1": {
          "type": "string"
        },
        "b1": {
          "type": "string"
        }
      },
      "required": [
        "a1",
        "b1"
      ],
      "type": "object"
    },
    "B2": {
      "additionalProperties": false,
      "properties": {
        "a1": {
          "type": "string"
        },
        "b2": {
          "type": "string"
        }
      },
      "required": [
        "a1",
        "b2"
      ],
      "type": "object"
    }
  }
}

Thanks a lot.

julienvincent commented 2 years ago

This looks related to an issue I reported a while ago: https://github.com/vega/ts-json-schema-generator/issues/952

domoritz commented 2 years ago

Thanks for finding a potential duplicate. It's hard to know until looking further into it but once someone can take a closer look, we can see whether they are the same.

thw0rted commented 2 years ago

I came across the same problem and just had to refactor my code to use a union plus an intersection, instead of Omit. It can make the types a bit more complicated but the schema comes out cleaner if the various intermediate types have names.

poudelroshan commented 1 year ago

Looking for a resolution to this issue. Occurs when using Pick with Exclude or when using Omit.

arthurfiorette commented 4 months ago

Currently, Pick, Exclude and Omit are not fully supported by this library. I'm happy to review pull requests :)

arthurfiorette commented 4 months ago

Probably also related to https://github.com/vega/ts-json-schema-generator/issues/189