Joi:要求三个字段中的两个不为空

Joi: Require exactly two of three fields to be non-empty

这是我的模式的简单版本。

var schema = Joi.object().keys({
    a: Joi.string(),
    b: Joi.string(),
    c: Joi.string()
});

我希望 a、b、c 恰好是 3 个非空中的 2 个。即:

已尝试使用 .or(),但显然行不通。调查了 .alternatives() 但没有成功。

很难找到一种优雅的方式来处理这个问题而不陷入循环依赖问题。我已经设法使用 .alternatives() and .try().

得到了一些东西

原始形式的解决方案是这样的:

Joi.alternatives().try(
    Joi.object().keys({
        a: Joi.string().required(),
        b: Joi.string().required(),
        c: Joi.string().required().valid('')
    }),
    Joi.object().keys({
        a: Joi.string().required().valid(''),
        b: Joi.string().required(),
        c: Joi.string().required()
    }),
    Joi.object().keys({
        a: Joi.string().required(),
        b: Joi.string().required().valid(''),
        c: Joi.string().required()
    })
);

它肯定不漂亮,如果引入更多依赖项,它可能会变得非常臃肿。

为了减少重复次数,以下方法也行得通:

var base = {
    a: Joi.string().required(),
    b: Joi.string().required(),
    c: Joi.string().required()
};

Joi.alternatives().try(
    Joi.object().keys(Object.assign({}, base,
    {
        a: base.a.valid('')
    })),
    Joi.object().keys(Object.assign({}, base,
    {
        b: base.b.valid('')
    })),
    Joi.object().keys(Object.assign({}, base,
    {
        c: base.c.valid('')
    }))
);