typescript-json-schema icon indicating copy to clipboard operation
typescript-json-schema copied to clipboard

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

Open leqwasd opened this issue 3 years ago • 0 comments

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:
{
    "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
{
    "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`
{
    "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`
{
    "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.

leqwasd avatar May 05 '22 17:05 leqwasd