alternatives().conditional() 和 any().when() 有什么区别?



直接来自文档,alternatives.conditional

添加条件备用架构类型(基于另一个键值或透视当前值的架构

)

any.when

添加在验证期间评估的条件,并在将架构应用于值之前对其进行修改

它们有何不同?具体来说,一个的结果什么时候会与另一个的结果不同?


我在alternatives.conditional文档中发现了有关any.when的说明:

请注意,alternatives.conditional()any.when()不同。当您使用any.when()时,您最终会得到所有匹配条件的复合模式,而alternatives.conditional()将使用第一个匹配的模式,忽略其他条件语句。

但我不明白,这是什么意思?

<小时 />

参考资料:

  • Joi docs: alternatives().conditional()
  • Joi docs: any().when()

看看这句话:

alternatives.conditional()将使用第一个匹配的架构,忽略其他条件语句。

如果您有多个conditionals()则只有第一个匹配的会影响密钥的架构。

Joi.object({
a: Joi.alternatives()
.conditional("c", { is: Joi.number().min(10), then: Joi.forbidden() })
.conditional("b", {
is: Joi.exist(),
then: Joi.valid("y"),
otherwise: Joi.valid("z"),
}),
b: Joi.any(),
c: Joi.number(),
});

对于上述架构,如果对象的键c小于 10,则只有第二个条件才会生效。 意义

{ a : 'z' , c : 11 , b : 2 }会说,"a"是不允许的(第一个条件)。 但是{ a : 'z' , c : 7 , b : 2 }会说,"a"必须是[y](第二个条件)。

如果您调整上述条件以执行以下操作(我只添加了一个otherwise子句):

Joi.object({
a: Joi.alternatives()
.conditional("c", {
is: Joi.number().min(10),
then: Joi.forbidden(),
otherwise: Joi.valid("x"),
})
.conditional("b", {
is: Joi.exist(),
then: Joi.valid("y"),
otherwise: Joi.valid("z"),
}),
b: Joi.any(),
c: Joi.number(),
});

然后,您有一个无效的架构,错误为:Unreachable condition。因为这里的第一个条件肯定会产生一些东西(它既有then又有otherwise)。

但据此:

当您使用any.when()时,您最终会得到所有匹配条件的复合架构

通过any.when()整个链被读取直到结束,以决定最终的模式。

const schema = {
a: Joi.any()
.valid("x")
.when("b", {
is: Joi.exist(),
then: Joi.valid("y"),
otherwise: Joi.valid("z"),
})
.when("c", { is: Joi.number().min(10), then: Joi.forbidden() }),
b: Joi.any(),
c: Joi.number(),
};

b存在时,ya的有效值,但是当c是一个大于等于10的数字时,不允许a

例如,下面是上述架构的有效对象:

{
a: 'y', //'x' also works
b: 20,
c: 9
}

但这不是:

{
a: 'y',
b: 20,
c: 10
}

此外,替代项会添加一个额外的替代项来尝试并且不会影响原始类型。

请看下面的架构:

Joi.object({
a: Joi.alternatives(["x"]).conditional("b", {
is: true,
then: Joi.forbidden(),
}),
b: Joi.boolean(),
});

{ b: true, a: 'x' }会通过的。Joi.forbidden()不会影响有效值x打开的事实。如果你通过{ b: true , a: 'y' },这肯定会失败,你会看到"a" is not allowed

如果您使用when编写上述规则:

Joi.object({
a: Joi.valid("x").when("b", { is: true, then: Joi.forbidden() }),
b: Joi.boolean(),
});

然后,{ b : true, a: 'x' }将按预期失败,因为这可能会影响密钥的整体类型when

最新更新