YousefED / typescript-json-schema

Generate json-schema from your Typescript sources
BSD 3-Clause "New" or "Revised" License
3.17k stars 323 forks source link

BUG: Union type unioned with other issues if used multiple time (With option: noExtraProps: true) #477

Open leqwasd opened 2 years ago

leqwasd commented 2 years ago

Given this test case:

interface TypeEqual {
    type: "=",
    value: string
}
interface TypeNotIn {
    type: "not in",
    value: string[]
}
type Types = TypeEqual  | TypeNotIn;
type WithMessage = { message: string }
type TypesWithMessage = Types & WithMessage;

type MyTypedObject = {
    type: Types;
    typeWithMessage: TypesWithMessage;
}
Produces this output: ```json { "type": "object", "properties": { "type": { "anyOf": [ { "$ref": "#/definitions/TypeEqual" }, { "$ref": "#/definitions/TypeNotIn" } ] }, "typeWithMessage": { "anyOf": [ { "additionalProperties": false, "type": "object", "properties": { "message": { "type": "string" } }, "required": [ "message" ] }, { "additionalProperties": false, "type": "object", "properties": { "message": { "type": "string" } }, "required": [ "message" ] } ] } }, "additionalProperties": false, "required": [ "type", "typeWithMessage" ], "definitions": { "TypeEqual": { "type": "object", "properties": { "type": { "type": "string", "enum": [ "=" ] }, "value": { "type": "string" } }, "additionalProperties": false, "required": [ "type", "value" ] }, "TypeNotIn": { "type": "object", "properties": { "type": { "type": "string", "enum": [ "not in" ] }, "value": { "type": "array", "items": { "type": "string" } } }, "additionalProperties": false, "required": [ "type", "value" ] } }, "$schema": "http://json-schema.org/draft-07/schema#" } ```

Note - problem is for properties on typeWithMessage

If I remove option noExtraProps: true, then

Produces it produces this output which is correct, but not what I need ```json { "type": "object", "properties": { "type": { "anyOf": [ { "$ref": "#/definitions/TypeEqual" }, { "$ref": "#/definitions/TypeNotIn" } ] }, "typeWithMessage": { "anyOf": [ { "allOf": [ { "$ref": "#/definitions/TypeEqual" }, { "type": "object", "properties": { "message": { "type": "string" } }, "required": [ "message" ] } ] }, { "allOf": [ { "$ref": "#/definitions/TypeNotIn" }, { "type": "object", "properties": { "message": { "type": "string" } }, "required": [ "message" ] } ] } ] } }, "required": [ "type", "typeWithMessage" ], "definitions": { "TypeEqual": { "type": "object", "properties": { "type": { "type": "string", "enum": [ "=" ] }, "value": { "type": "string" } }, "required": [ "type", "value" ] }, "TypeNotIn": { "type": "object", "properties": { "type": { "type": "string", "enum": [ "not in" ] }, "value": { "type": "array", "items": { "type": "string" } } }, "required": [ "type", "value" ] } }, "$schema": "http://json-schema.org/draft-07/schema#" } ```

If I change the definition of MyTypedObject to this:

type MyTypedObject = {
    // type: Types;
    typeWithMessage: TypesWithMessage;
}

Then the output is correct for both:

`noExtraProps: false` ```json { "type": "object", "properties": { "typeWithMessage": { "anyOf": [ { "additionalProperties": false, "type": "object", "properties": { "type": { "type": "string", "enum": [ "=" ] }, "value": { "type": "string" }, "message": { "type": "string" } }, "required": [ "message", "type", "value" ] }, { "additionalProperties": false, "type": "object", "properties": { "type": { "type": "string", "enum": [ "not in" ] }, "value": { "type": "array", "items": { "type": "string" } }, "message": { "type": "string" } }, "required": [ "message", "type", "value" ] } ] } }, "additionalProperties": false, "required": [ "typeWithMessage" ], "$schema": "http://json-schema.org/draft-07/schema#" } ```
`noExtraProps: true` ```json { "type": "object", "properties": { "typeWithMessage": { "anyOf": [ { "allOf": [ { "$ref": "#/definitions/TypeEqual" }, { "type": "object", "properties": { "message": { "type": "string" } }, "required": [ "message" ] } ] }, { "allOf": [ { "$ref": "#/definitions/TypeNotIn" }, { "type": "object", "properties": { "message": { "type": "string" } }, "required": [ "message" ] } ] } ] } }, "required": [ "typeWithMessage" ], "definitions": { "TypeEqual": { "type": "object", "properties": { "type": { "type": "string", "enum": [ "=" ] }, "value": { "type": "string" } }, "required": [ "type", "value" ] }, "TypeNotIn": { "type": "object", "properties": { "type": { "type": "string", "enum": [ "not in" ] }, "value": { "type": "array", "items": { "type": "string" } } }, "required": [ "type", "value" ] } }, "$schema": "http://json-schema.org/draft-07/schema#" } ```

This was working on 0.42.0. I can't update because of this.