import {ArrayValidator} from './composite/array' import {ConstantValidator} from './composite/constant' import {Default} from './composite/default' import {GetKeyTaggedUnionCast, GetKeyTaggedUnionSrc, KeyTaggedUnionValidator} from './composite/key-tagged-union' import {NullableValidator} from './composite/nullable' import {GetPropsCast, GetPropsSrc, ObjectValidator} from './composite/object' import {GetOneOfCast, GetOneOfSrc, OneOfValidator} from './composite/one-of' import {OptionValidator} from './composite/option' import {RecordValidator} from './composite/record' import {RefValidator} from './composite/ref' import {Sentinel} from './composite/sentinel' import {GetTaggedUnionCast, GetTaggedUnionSrc, TaggedUnion} from './composite/tagged-union' import {TupleValidator} from './composite/tuple' import {DataValidationError, ValidationFailure} from './error' import {GetCastType, GetSrcType, Validator} from './interface' export function object | undefined>>( props: Props ): Validator, GetPropsSrc> { let presentProps: Record> = {} for (let key in props) { let v = props[key] if (v) { presentProps[key] = v } } return new ObjectValidator(presentProps) as any } export function record, V extends Validator>( key: K, value: V ): Validator< Record, GetCastType>, Record, GetSrcType> > { return new RecordValidator(key, value) } export function taggedUnion>>( field: F, variants: U ): Validator, GetTaggedUnionSrc> { return new TaggedUnion(field, variants) } export function keyTaggedUnion>>( variants: U ): Validator, GetKeyTaggedUnionSrc> { return new KeyTaggedUnionValidator(variants) } export function tuple>(t: T): Validator<[GetCastType], [GetSrcType]> export function tuple, T2 extends Validator>(t1: T1, t2: T2): Validator<[GetCastType, GetCastType], [GetSrcType, GetSrcType]> export function tuple, T2 extends Validator, T3 extends Validator>(t1: T1, t2: T2, t3: T3): Validator<[GetCastType, GetCastType, GetCastType], [GetSrcType, GetSrcType, GetSrcType]> export function tuple(...tuple: Validator[]): Validator { return new TupleValidator(tuple) } export function array>(item: V): Validator[], GetSrcType[]> { return new ArrayValidator(item) } export function option>(item: V): Validator< GetCastType | undefined, GetSrcType | undefined | null > { return new OptionValidator(item) } export function nullable>(item: V): Validator< GetCastType | null, GetSrcType | null > { return new NullableValidator(item) } export function withSentinel>( label: string, value: GetCastType, validator: V ): Validator, GetSrcType | undefined | null> { return new Sentinel(label, value, validator) } export function withDefault>( value: GetCastType, validator: V ): Validator, GetSrcType | undefined | null> { return new Default(value, validator) } export function ref>(get: () => V): Validator, GetSrcType> { return new RefValidator(get) } export function oneOf

>>( patterns: P ): Validator, GetOneOfSrc

> { return new OneOfValidator(patterns) } export function constant(value: T, equals?: (a: unknown, b: T) => boolean) { return new ConstantValidator(value, equals) } export function cast>(validator: V, value: unknown): GetCastType { let result = validator.cast(value) if (result instanceof ValidationFailure) throw new DataValidationError(result.toString()) return result } export function assertValidity>( validator: V, value: unknown ): asserts value is GetSrcType { let err = validator.validate(value) if (err) throw new DataValidationError(err.toString()) }