我需要使用joi
验证模式。
对象是这样的:
TYPE1
,TYPE2
,TYPE3
。type === 'TYPE1'
,我们必须期望属性one
,two
和three
处于同一级别。type === 'TYPE2'
,我们必须期望属性four
,five
和six
处于同一级别。type === 'TYPE3'
,我们必须期望一个subtype
属性处于同一级别,并可能具有值A
和B
。
subtype === 'A'
,那么我们必须期望属性seven
,eight
,nine
处于同一级别。subtype === 'B'
,那么我们必须期望属性ten
,eleven
,twelve
处于同一级别。这是我想出的:
import { object, string, validate } from 'joi';
const obj1 = { // valid
type: 'TYPE1',
one: '01',
two: '02',
three: '03',
};
const obj2 = { // valid
type: 'TYPE2',
four: '04',
five: '05',
six: '06',
};
const obj3 = { // valid
type: 'TYPE3',
subtype: 'A',
seven: '07',
eight: '08',
nine: '09',
};
const obj4 = { // valid
type: 'TYPE3',
subtype: 'B',
ten: '10',
eleven: '11',
twelve: '12',
};
const joiSchema = object({
// point 1
type: string().valid('TYPE1', 'TYPE2', 'TYPE3').required(),
})
.when(
// point 2
object({ type: 'TYPE1' }).unknown(),
{
then: object({
one: string().required(),
two: string().required(),
three: string().required(),
}),
},
)
.when(
// point 3
object({ type: 'TYPE2' }).unknown(),
{
then: object({
four: string().required(),
five: string().required(),
six: string().required(),
}),
},
)
.when(
// point 4
object({ type: 'TYPE3' }).unknown(),
{
then: object(
// if type === 'TYPE3', check for one of those schemas
{
// point 4
subtype: string().valid('A', 'B'),
},
).when(
// point 4.1
object({ subtype: 'A' }).unknown(),
{
then: object({
seven: string().required(),
eight: string().required(),
nine: string().required(),
}),
},
).when(
// point 4.2
object({ subtype: 'B' }).unknown(),
{
then: object({
ten: string().required(),
eleven: string().required(),
twelve: string().required(),
}),
},
),
},
);
const result1 = validate(obj1, joiSchema);
console.log('Validating obj1')
if (result1.error) {
console.error(result1.error.message);
}
const result2 = validate(obj2, joiSchema);
console.log('Validating obj2')
if (result2.error) {
console.error(result2.error.message);
}
const result3 = validate(obj3, joiSchema);
console.log('Validating obj3')
if (result3.error) {
console.error(result3.error.message);
}
const result4 = validate(obj4, joiSchema);
console.log('Validating obj4')
if (result4.error) {
console.error(result4.error.message);
}
此代码段可在此处进行测试:https://repl.it/@AlessandroDe5/Joi-MCVE
它显示此错误:
AssertionError [ERR_ASSERTION]: Cannot merge type object with another type: alternatives
at new AssertionError (internal/errors.js:315:11)
at Object.exports.assert (/home/runner/node_modules/hoek/lib/index.js:559:11)
at internals.Object.concat (/home/runner/node_modules/joi/lib/types/any/index.js:148:14)
at internals.Alternatives.when (/home/runner/node_modules/joi/lib/types/alternatives/index.js:131:52)
at index.ts:52:6
at Script.runInThisContext (vm.js:65:33)
at startRepl (/usr/local/lib/node_modules/ts-node-fm/src/bin.ts:157:12)
at Object.<anonymous> (/usr/local/lib/node_modules/ts-node-fm/src/bin.ts:66:1)
at Module._compile (internal/modules/cjs/loader.js:654:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:665:10)
如果我删除嵌套的when
(第4、4.1、4.2点),它将正常工作并且当然会拒绝最后两个对象。
我还尝试将when
替换为alternatives
:
.when(
// point 4
object({ type: 'TYPE3' }).unknown(),
{
then: alternatives().try(
object({
subtype: string().valid('A'),
seven: string().required(),
eight: string().required(),
nine: string().required(),
}),
).when(
object({
subtype: string().valid('B'),
ten: string().required(),
eleven: string().required(),
twelve: string().required(),
}),
),
},
);
可以预料到我会得到完全相同的错误。
有办法以某种方式完成任务吗?
答案 0 :(得分:0)
我建议使用 Joi.alternatives(),这是另一种方法,这样可以避免嵌套何时,因此您的架构应如下所示:
Joi.alternatives().try(
Joi.object({
type: Joi.string().valid('TYPE1').required(),
one: Joi.string().required(),
two: Joi.string().required(),
three: Joi.string().required(),
}),
Joi.object({
type: Joi.string().valid('TYPE2').required(),
four: Joi.string().required(),
five: Joi.string().required(),
six: Joi.string().required(),
}),
Joi.object({
type: Joi.string().valid('TYPE3').required(),
subtype: Joi.string().valid('A', 'B')
})
.when(Joi.object({ subtype: 'A' }).unknown(), {
then: Joi.object({
seven: Joi.string().required(),
eight: Joi.string().required(),
nine: Joi.string().required(),
}),
})
.when(Joi.object({ subtype: 'B' }).unknown(), {
then: Joi.object({
ten: Joi.string().required(),
eleven: Joi.string().required(),
twelve: Joi.string().required(),
}),
}),
);