You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在JSON Schema中表示多态对象,实现按type字段动态校验

问题原因分析

你的Schema核心问题出在additionalProperties: false的作用域规则:

JSON Schema draft-07 中,additionalProperties 只能识别同层级properties、patternProperties 中声明的属性,无法识别父层级或者其他分支中定义的属性。

你把additionalProperties: false写在了每个then分支内,而分支内的properties只声明了value/min/max,没有声明顶层定义的type属性,所以分支校验生效时,type会被判定为非法额外属性,这就是第一个测试用例提示type未定义的原因。

而第二个测试用例没按预期报错,本质是部分校验器对if/then+additionalProperties组合的处理优先级存在偏差,加上你的规则结构本身有逻辑缺陷,导致分支规则没有完全生效。


修复方案

方案1:兼容draft-07版本的调整

在每个then分支的properties中补充type的约束,让additionalProperties可以识别到type是合法属性:

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "properties": {
    "type": {
      "type": "string",
      "enum": ["INT", "PERCENT"]
    }
  },
  "required": ["type"],
  "allOf": [
    {
      "if": {
        "properties": {"type": {"const": "INT"}}
      },
      "then": {
        "properties": {
          "type": {"const": "INT"},
          "value": {"type": "number", "multipleOf": 1}
        },
        "required": ["value"],
        "additionalProperties": false
      }
    },
    {
      "if": {
        "properties": {"type": {"const": "PERCENT"}}
      },
      "then": {
        "properties": {
          "type": {"const": "PERCENT"},
          "value": {"type": "number"},
          "min": {"type": "number"},
          "max": {"type": "number"}
        },
        "required": ["value", "min", "max"],
        "additionalProperties": false
      }
    }
  ]
}

调整后两个测试用例都会触发预期的校验错误:

  • PERCENT类型用例不再报错type未定义
  • INT类型用例会同时触发三个错误:value不满足multipleOf: 1、min和max是额外不允许的属性。

方案2:升级到更高版本Schema(推荐)

如果可以使用draft 2019-09及以上版本,用unevaluatedProperties替代additionalProperties,可以简化写法,不需要重复声明type:

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "type": {
      "type": "string",
      "enum": ["INT", "PERCENT"]
    }
  },
  "required": ["type"],
  "unevaluatedProperties": false,
  "allOf": [
    {
      "if": {
        "properties": {"type": {"const": "INT"}}
      },
      "then": {
        "properties": {
          "value": {"type": "number", "multipleOf": 1}
        },
        "required": ["value"]
      }
    },
    {
      "if": {
        "properties": {"type": {"const": "PERCENT"}}
      },
      "then": {
        "properties": {
          "value": {"type": "number"},
          "min": {"type": "number"},
          "max": {"type": "number"}
        },
        "required": ["value", "min", "max"]
      }
    }
  ]
}

unevaluatedProperties会识别所有分支中声明的属性,以及顶层声明的type属性,逻辑更简洁,兼容性也在主流校验器中得到了支持。


内容的提问来源于stack exchange,提问作者VorpalSword

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 06:15:01