'JSON Schema conditional oneOf
I have a oneOf statement in my JSON Schema, but the validator should only allow one of the oneOf options to be selected depending on another value in the schema, for example:
If productType === car
Then asset === vehicle
If productType === rocket
Then asset === spaceship
I can't work out how to allow this, because my Typescript model looks like this:
Product
productType: ProductType;
asset: Vehicle | Spaceship;
Schema:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "myschemaID",
"type": "object",
"additionalProperties": false,
"productType": {
"type": "string",
"enum": ["car", "rocket"]
},
"asset": {
"oneOf": [
{ "$ref": "#/$defs/vehicle" },
{ "$ref": "#/$defs/spaceship" }
]
}
}
I've, knowing it won't work, have tried a conditional like this:
"asset": {
"if": {
"properties": { "productType": { "const": "car" } }
},
"then": {
"$ref": "#/$defs/vehicle"
},
"else": {
"$ref": "#/$defs/spaceship"
}
}
Any help achieving this in schema would be greatly appreciated.
Solution 1:[1]
Your main issue is that you are missing the properties keyword around your property definitions for "productType" and "asset".
In order for the if/then to work, it needs to be at the same level (or above) as all properties it needs to reference. So, you can't put it in the "asset" schema because then it can't check the "productType" property value in the if schema.
Unfortunately, the result is a bit verbose.
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "myschemaID",
"type": "object",
"properties": {
"productType": {
"type": "string",
"enum": ["car", "rocket"]
},
"asset": {}
},
"additionalProperties": false,
"allOf": [
{
"if": {
"type": "object",
"properties": {
"productType": { "const": "car" }
},
"required": ["productType"]
},
"then": {
"properties": {
"asset": { "$ref": "#/$defs/vehicle" }
}
}
},
{
"if": {
"type": "object",
"properties": {
"productType": { "const": "rocket" }
},
"required": ["productType"]
},
"then": {
"properties": {
"asset": { "$ref": "#/$defs/spaceship" }
}
}
}
]
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Jason Desrosiers |
