Option to generate `if-then-else` schema for union types
See original GitHub issueToday (v1.0.0) a union type like the following:
export type Fish = {
animal_type: 'fish';
found_in: 'ocean' | 'river';
};
export type Bird = {
animal_type: 'bird';
can_fly: boolean;
};
export type Animal = Bird | Fish;
Generates the following json schema:
"Animal": {
"anyOf": [
{
"$ref": "#/definitions/Bird"
},
{
"$ref": "#/definitions/Fish"
}
]
},
This fulfills the need to validate the schema. However, when there is an error schema validators like ajv
produce errors for all schema paths. As an example, { animal_type: 'fish', found_in: 'lake' }
results in the following error:
must have required property 'can_fly': can_fly [keyword: required, instancePath: , schemaPath: #/definitions/Bird/required]
must be equal to one of the allowed values: ocean,river [keyword: enum, instancePath: /found_in, schemaPath: #/definitions/Fish/properties/found_in/enum]
must match a schema in anyOf: [keyword: anyOf, instancePath: , schemaPath: #/anyOf]
This first line in this error can be misleading since animal_type
is fish
, and can_fly
is not a property of fish. The second line is the real error that we’d like to present.
The errors can get more confusing as you add more types to the union type… a lot of errors are shown for types that are irrelevant given the provide animal_type
.
A solution to this problem would be to have the option to generate if-then-else
json schemas. These provide more information to the validators to pick the appropriate schema. So if we generate the following:
"Animal": {
"type": "object",
"properties": {
"animal_type": {
"type": "string",
"enum": ["fish", "bird"]
}
},
"allOf": [
{
"if": {
"properties": { "animal_type": { "const": "fish" } }
},
"then": {
"$ref": "#/definitions/Fish"
}
},
{
"if": {
"properties": { "animal_type": { "const": "bird" } }
},
"then": {
"$ref": "#/definitions/Bird"
}
}
]
}
The same input results in the following, more concise error:
must be equal to one of the allowed values: ocean,river [keyword: enum, instancePath: /found_in, schemaPath: #/definitions/Fish/properties/found_in/enum]
Issue Analytics
- State:
- Created a year ago
- Comments:6 (3 by maintainers)
Top GitHub Comments
@mdesousa,
Excellent description.
I would push back on the validators. The validators have all the same information that this tool does. It is nearly impossible to know which field / fields to use as the type pivot. It gets even more complicated when you add sub-types.
The validator should be able to do a “best-fit” and give the appropriate error.
🚀 Issue was released in
v1.1.0
🚀