Joi有没有"not"的概念?

Does Joi have the concept of "not"?

问题

我有一个从 JSON 字符串中解析出来的对象。我想确认它的字段只包含原始类型(例如数字、布尔值、字符串)。具体来说,我想确认所有字段值都是 而不是 object.

Joi有not的概念吗?我可以在不列出所有可能的非对象类型的情况下执行此操作吗?

尝试

我尝试使用 any.disallow,这几乎是我所需要的(并且,我在发布问题后意识到,它被列为具有别名 not)。

import Joi from 'joi'

const schema = Joi.object().keys({ 
  myKey: Joi.any().not(Joi.object()),
})

然而,这似乎需要值。这意味着它不会与模式进行比较,并且会将任何不是 Joi.object() 返回的文字值的值视为有效。

目前看来,答案可能是否定的。

也就是说,可以为未融入 Joi 的逻辑定义 custom validation functions

像下面这样的东西确实有效:

import Joi from 'joi'

const schema = Joi.object().keys({ 
  myKey: Joi.any().custom(
    (value, helpers) => {
      if (typeof value === 'object' && value !== null) {
        return helpers.error('any.invalid');
      }
      return value
    },
    'is not an object',
  ),
})

我发现 this 允许您只接受基元,但它不是您正在寻找的 not

const example = { 2: 'str', 3: 4, 4: true, 5: { 3: 2 } }

Joi.object()
   .pattern(/^/, [Joi.boolean(), Joi.string(), Joi.number()])
   .validate(example)

基本上,/^/ 是接受任意键的正则表达式,数组是 Joi.alternatives.

的语法糖

编辑:我管理的架构在键为对象时失败

Joi.object()
   .pattern(/^/, Joi.when(Joi.object(), { then: Joi.forbidden() }))
   .validate(example)

我差一点就到了

Joi.object()
   .pattern(/^/, Joi.not(Object()))
   .validate(example)

但它只适用于空对象,例如 {},我怀疑这与 Joi.not 只接受文字有关。

我认为没有“不”选项。

这是另一种组合 .when and .forbidden:

const schema = Joi.object().keys({ 
  myKey: Joi.any(),
}).when(Joi.object({ myKey: Joi.object() }), {
    then: Joi.object({ myKey: Joi.forbidden() })
});