如何在JSON模式验证器中表示联合类型



我是JSON模式验证的新手,正在为配置构建自定义模式。我正在构建的架构是基于Typescript类型的。我了解如何验证简单的数据类型,如数组、对象、数字、字符串等。

但是有没有一种方法可以指定这样的类型:

type Conf = {
idle_session_timeout?: number | "none";
item:
| {
kind: "attribute";
name: string;
}
| {
kind: "relation";
name: string;
}
| {
kind: "group";
name: string;
label?: string | undefined;
entries: PresentationItem[];
};
order_by:
| string
| {
attribute: string;
direction?: "asc" | "desc" | undefined;
};
};

我注意到http://json-schema.org/draft-07/schema它支持if-then-else语句根据值切换验证模式,但我不知道如何实现它们。

有几个关键字需要注意,可能是指的规范

首先,"类型"允许在一个数组中指定多个值。有了这个,你可以指定例如["string", "number"]来表示"字符串或数字"。许多关键字只适用于实例为特定JSON类型的情况。通常,如果所有剩余的关键字仅适用于相应的类型,则可以将一个"类型"的架构和另一个具有不同"类型"。

因此,作为一个例子,您可以有两个模式,如:

{
"type": "string",
"minLength": 1
}
{
"type": "number",
"minimum": 0
}

因为"minimum"只适用于数字,而"minLength"只应用于字符串,所以您可以简单地将模式组合在一起,它将具有相同的效果:

{
"type": ["string", "number"],
"minLength": 1
"minimum": 0
}

但是,对于相同"类型"的两个模式,这样做将执行交集而不是并集。这是因为将关键字添加到JSON模式会添加约束,而将值添加到"类型"列表则会删除约束(更多值将生效(。

因此,如果您正在对同一"类型"的两个架构执行并集,或者如果您正在将架构与在所有类型中验证的关键字(特别是"enum"或"const"(组合,则需要将它们与"anyOf"关键字组合,后者对多个架构的数组执行并集。(您也可以考虑"oneOf"。(


我想你最终会得到这样的模式:

{
"type": "object",
"properties": {
"idle_session_timeout": {
"type": ["number","string"],
"anyOf": [ {"type":"number"}, {"const":"none"} ]
},
"item": {
"type": "object",
"required": ["kind", "name"],
"properties": {
"kind": { "type": "string" },
"name": { "type": "string" },
},
"anyOf": [
{
"properties": {
"kind": { "const": "attribute" },
}
},
{
"properties": {
"kind": { "const": "relation" },
}
},
{
"required": ["entries"],
"properties": {
"kind": { "const": "group" },
"label": { "type": "string" },
"entries": { "type":"array", "items": {"$ref":"PresentationItem"} },
}
}
]
},
"order_by": {
"type": ["string", "object"],
"required": ["attribute"],
"properties": {
"attribute": { "type": "string" },
"direction": { "enum": ["asc", "desc"] },
}
}
}

请注意,我是如何将"anyOf"中的常见关键字分解为尽可能高的级别的。这是一个风格上的选择。它会产生稍微干净的错误,但它可能与您无关,这取决于您计划如何扩展模式。

最新更新