基于数组元素的条件验证 - 避免警告 'missing type "object" for keyword "properties"'

Conditional validation based on array element - Avoid warning 'missing type "object" for keyword "properties"'

我有一个 JSON 数组,其中包含具有键值对的对象。

[
    { "name": "foo" },
    { "name": "bar" }
]

如果 name 中的一个等于 null 我想将 maxItems 设置为 1

我的架构如下所示:

{
    "type": "array",
    "minItems": 1,
    "items": {
        "type": "object",
        "properties": {
            "name": {
                "enum": [null, "foo", "bar"]
            }
        },
        "required": [
            "name"
        ]
    },
    "if": {
        "contains": { "properties": { "name": { "const": null } } }
    },
    "then": {
        "maxItems": 1
    }
}

基本可以,但在编译时输出警告:

strict mode: missing type "object" for keyword "properties" at "#/if/contains" (strictTypes)

我知道 properties 只是对象的关键字,我在这里将它应用于数组的一个实例(实际上意味着:数组对象之一的属性),但我不知道如何妥善解决这个问题。

一个完整的 AJV 最小示例如下所示:

const Ajv = require('ajv');
const ajv = new Ajv();

const schema = {
    "type": "array",
    "minItems": 1,
    "items": {
        "type": "object",
        "properties": {
            "name": {
                "enum": [null, "foo", "bar"]
            }
        },
        "required": [
            "name"
        ]
    },
    "if": {
        "contains": { "properties": { "name": { "const": null } } }
    },
    "then": {
        "maxItems": 1
    }
};

const data = [
    { name: 'foo' },
    { name: 'bar' }
];

const data2 = [
    { name: null }
];

const data3 = [
    { name: 'foo' },
    { name: null }
];

const validate = ajv.compile(schema); // strict mode: missing type "object" for keyword "properties" at "#/if/contains" (strictTypes)
console.log(validate(data)); // true
console.log(validate(data2)); // true
console.log(validate(data3)); // false

关键字 contains 的定义表明其值必须是有效的 JSON 模式。所以这个警告是有道理的。为什么不简单地向 contains 处的模式添加 "type": "object"

在你看来,作为一个人,这可能没有必要,因为你已经 'know' 这些值是对象,但验证器确实期望这里的完整模式适用于每个数组值。

规范并未强制要求 "type": "object" 必须与 object-specific 关键字一起出现,例如 properties。 (事实上​​ ,混合和匹配对应于不同类型的关键字通常很有用,以允许灵活的数据输入。)然而,ajv 实现坚持这样做。

此时您的选择是添加额外的关键字,请求实现作者修复此行为,或者切换到不同的实现。