Closed MentalGear closed 6 months ago
@MentalGear Hi,
TypeBox will terminate on the first error with Check
by default. Internally, this is done using chained logical expressions (A && B && C
) where if A
fails, condition B
and C
are not checked.
const A = () => { console.log('A'); return false }
const B = () => { console.log('B'); return true }
const C = () => { console.log('C'); return true }
const R = A() && B() && C() // only A is printed
All checks are implemented using logical expressions like the above.
Unlike Check, TypeBox uses an iterator system for Errors. Because errors may need to be exhaustive, the Check logic is re-implemented for the Errors to "NOT use chained expressions" and to "NOT terminate on error". Instead the Errors function will yield
at each failure case and continue
....the caller receiving the errors can chose to yield only the first (terminate on error) or all (exhaustive checking)
const T = Type.Object({ ... })
const F = Value.Errors(T, { ... }).First() // terminate at first error
const A = [...Value.Errors(T, { ... })] // exhaustive errors
This means that there no need to implement a strict mode, as the caller can chose either first
or exhaustive
processing by receiving values of the iterator.
Putting it all together, the following implements a Parse function using both Check and Errors.
import { Type, Static, TSchema } from '@sinclair/typebox'
import { Value } from '@sinclair/typebox/value'
export function Parse<T extends TSchema>(schema: T, value: unknown): Static<T> {
if(Value.Check(schema, value)) return value // check and return
const first = Value.Errors(schema, value).First()! // optionally gather diagnostics
throw Error(first.message) // ... and throw
}
const A = Parse(Type.String(), 'hello')
It's not clear whether this library provides a bail / early cancel mode to throw if already one property fails to validate. This would greatly help server running costs. As typebox is really performance minded, this 'strict' mode with 'bail' would make a great addition. Thank you!