50 lines
1.2 KiB
TypeScript
50 lines
1.2 KiB
TypeScript
import SchemaItem from '../SchemaItem'
|
|
import { SchemaInfer, ValidationResult } from '../types'
|
|
|
|
type ItemType<T extends Array<SchemaItem>> = SchemaInfer<T[number]>
|
|
export default class SchemaUnion<T extends Array<SchemaItem>> extends SchemaItem<ItemType<T>> {
|
|
|
|
private schemas: T
|
|
|
|
public constructor(...schemas: T) {
|
|
super()
|
|
this.schemas = schemas
|
|
}
|
|
|
|
public parse(input: unknown, options?: { fast?: boolean }): ValidationResult<SchemaInfer<T[number]>> {
|
|
|
|
// check errors from itself
|
|
const { valid, object, errors = [] } = super.parse(input, options)
|
|
|
|
// skip checking childs if self is not valid (maybe still try to check childs whan fast is false ?)
|
|
if (!valid) {
|
|
return {
|
|
valid,
|
|
object,
|
|
errors
|
|
} as ValidationResult<SchemaInfer<T[number]>>
|
|
}
|
|
|
|
// loop through the childs
|
|
for (const schema of this.schemas) {
|
|
const validation = schema.parse(input, options)
|
|
if (validation.valid) {
|
|
return validation
|
|
} else {
|
|
errors.push(...validation.errors)
|
|
}
|
|
}
|
|
|
|
// answer !
|
|
return {
|
|
valid: false,
|
|
errors: errors,
|
|
object: object
|
|
} as ValidationResult<SchemaInfer<T[number]>>
|
|
}
|
|
|
|
public override isOfType(input: unknown): input is ItemType<T> {
|
|
return this.schemas.some((it) => it.isOfType(input))
|
|
}
|
|
}
|