JSON Schema中oneOf与additionalProperties使用困惑及修正咨询
修正JSON Schema以禁止额外属性并保留鉴别器功能
问题根源
你的Schema允许额外属性,是因为Common、Type1和Type2都配置了additionalProperties: true,且通过allOf组合时,子Schema的宽松约束会覆盖主Schema的严格限制。直接全局设置additionalProperties: false失效,也是因为子Schema的true优先级导致约束冲突。
修正方案
调整Schema结构,将公共属性与类型专属属性合并,并在每个类型定义中明确禁止额外属性,同时保留type作为鉴别器的功能:
{ "$id": "foo.schema.json", "oneOf": [ { "$ref": "#/$defs/Type1" }, { "$ref": "#/$defs/Type2" } ], "$defs": { "Common": { "type": "object", "properties": { "title": { "type": "string" } }, "required": ["title"] }, "Type1": { "allOf": [ { "$ref": "#/$defs/Common" }, { "type": "object", "properties": { "type": { "const": "type1" } }, "required": ["type"] } ], "additionalProperties": false }, "Type2": { "allOf": [ { "$ref": "#/$defs/Common" }, { "type": "object", "properties": { "type": { "const": "type2" } }, "required": ["type"] } ], "additionalProperties": false } } }
方案说明
- 类型鉴别:主Schema通过
oneOf确保对象只能匹配Type1或Type2,自动拒绝type为type3的情况 - 公共属性约束:
Common定义了必填的title字符串属性,所有类型都继承该约束 - 禁止额外属性:每个类型定义末尾设置
additionalProperties: false,仅允许title和对应type属性(后续可扩展专属属性) - 必填校验:
Common和各类型分别约束title、type为必填,自动拒绝缺少type的对象
后续扩展专属属性
如果需要给Type1或Type2添加专属属性,只需在对应类型的properties中新增字段即可,例如给Type1添加detail属性:
"Type1": { "allOf": [ { "$ref": "#/$defs/Common" }, { "type": "object", "properties": { "type": { "const": "type1" }, "detail": { "type": "string" } // 新增专属属性 }, "required": ["type"] } ], "additionalProperties": false }
这样既保留了鉴别器功能,又严格控制了属性范围,完全满足你的校验需求。
内容的提问来源于stack exchange,提问作者Onkeltem
相关产品推荐
相关产品推荐

