直接来自文档,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
存在时,y
是a
的有效值,但是当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
。