Closed AntonioAngelino closed 1 year ago
@AntonioAngelino Hi!
TypeBox validators don't support conditional schematics (currently, but it's on my list of things to do), but Ajv does. You can express schematics (as you've described) using JSON schema if/then/else
keywords, the following is how you could express such a type in TypeBox (using Ajv to validate)
import { Type } from '@sinclair/typebox'
const T = Type.Object({ // this schema must pass
a: Type.Optional(Type.String()),
b: Type.Optional(Type.String()),
c: Type.Optional(Type.String()),
d: Type.Optional(Type.Number())
}, {
if: Type.Object({ // but if this schema passes (allowing c, d only)
c: Type.Optional(Type.String()),
d: Type.Optional(Type.Number())
}, { additionalProperties: false }),
then: Type.Not(Type.Any()), // then use this schema (not anything)
})
import Ajv from 'ajv'
const ajv = new Ajv()
console.log(ajv.validate(T, { a: 'This is valid', c: 'test', d: 123 })) // true
console.log(ajv.validate(T, { b: 'This is valid', c: 'test', d: 123 })) // true
console.log(ajv.validate(T, { a: 'This is valid...', b: '...too', c: 'test', d: 123 })) // true
console.log(ajv.validate(T, { c: 'Invalid!!!', d: 123 })) // false
There are likely a number of different ways could express this. You can find additional information on conditional schematics at the following link (just be a bit mindful these kinds of schematics can get very complex)
https://json-schema.org/understanding-json-schema/reference/conditionals.html#id6
Hope that helps! S
@AntonioAngelino Hi, might close up this issue.
Will be looking to implement if/then/else
in subsequent updates to the Compiler (which are due for an update), may also take a look at dependentRequired
as part of that work also, however I don't expect updates to be done before September, so for now, do recommend Ajv for these kinds of conditional schematics.
Also, with the previous example, just note you can also replace
Type.Not(Type.Any())
withType.Never()
which is semantically the same (and may read a little clearer)
const T = Type.Object({ // this schema must pass
a: Type.Optional(Type.String()),
b: Type.Optional(Type.String()),
c: Type.Optional(Type.String()),
d: Type.Optional(Type.Number())
}, {
if: Type.Object({ // but if this schema passes (allowing c, d only)
c: Type.Optional(Type.String()),
d: Type.Optional(Type.Number())
}, { additionalProperties: false }),
then: Type.Never(), // then never
})
If you have any follow up questions, feel free to reply on this thread. All the best! S
I need to validate the following JSON objects. Both properties "A" and "B" cannot be optional simultaneously. If "A" is undefined, then "B" must be set to pass the checks (and vice-versa).
Is there a way of doing it with TypeBox? Thank you.