JSON Schema Draft 7 如何限制对象仅使用指定集合中的单个属性
基础场景:myObject 仅允许包含指定属性中的恰好一个
你原来的写法不生效的核心原因是oneOf只校验了「必须存在某个属性」,没有限制其他属性同时存在,结合Draft 7的特性,推荐采用properties: { 属性名: false }的方式实现属性互斥,该方式报错提示清晰,同时兼容编辑器自动补全:
- 先把互斥属性的基础schema和单属性允许规则抽入
definitions复用:
"definitions": { // 所有互斥属性的基础定义 "exclusiveOptionProps": { "properties": { "a": {...}, "b": {...}, "c": {...}, // 其他十余种属性依次补充 } }, // 单属性互斥规则,每个规则要求必须存在对应属性,且禁止其他互斥属性 "only-a": { "required": ["a"], "properties": { "b": false, "c": false, // 其他属性依次设为false } }, "only-b": { "required": ["b"], "properties": { "a": false, "c": false, // 其他属性依次设为false } }, // 其余属性的only规则依次补充 }
- 基础myObject定义如下:
"myObject": { "type": "object", "$ref": "#/definitions/exclusiveOptionProps", "oneOf": [ {"$ref": "#/definitions/only-a"}, {"$ref": "#/definitions/only-b"}, {"$ref": "#/definitions/only-c"}, // 其余only规则依次引用 ], "additionalProperties": false }
该写法下,如果同时填写a和b,校验器会直接提示"b"属性不被允许,而非模糊的属性数量错误。
扩展场景:myExtendedObject 额外包含op、val属性
不需要修改原有基础规则,直接复用抽离的定义即可:
"myExtendedObject": { "type": "object", "required": ["op", "val"], "allOf": [ {"$ref": "#/definitions/exclusiveOptionProps"}, { "properties": { "op": {...}, "val": {...} } }, { "oneOf": [ {"$ref": "#/definitions/only-a"}, {"$ref": "#/definitions/only-b"}, {"$ref": "#/definitions/only-c"}, // 其余only规则依次引用 ] } ], "additionalProperties": false }
该结构会自动满足:必须存在op、val + 恰好存在一个互斥属性组中的属性,无额外规则冲突。
简化重复代码的技巧
如果互斥属性数量较多,不需要手动编写每个only-x规则,可以写一个简单的脚本批量生成:输入属性列表,自动生成对应definitions下的单属性规则和oneOf引用数组,完全避免手动重复编写。
内容的提问来源于stack exchange,提问作者Phil W
相关产品推荐
相关产品推荐

