import { RuleFn } from '../rules/types'; export { RuleFn }; export type TypeGuard = (value: unknown) => value is T; export type TypeChecker = (value: unknown) => boolean; export type ErrorReporter = (message: string, context: string | undefined, code?: string) => never; export type NonEmptyArray = [T, ...T[]]; export type ErrorMessage = { context: string | undefined; message: string; }; export type ValidationSuccess = { ok: true; result: T; errors: []; }; export type ValidationFailure = { ok: false; result: undefined; errors: NonEmptyArray; }; export type ValidationResult = ValidationSuccess | ValidationFailure; export interface CasterFn { (value: unknown, context?: string, reportError?: ErrorReporter): T; name: string; } export interface Caster extends CasterFn { optional: Caster; nullable: Caster; restrict(...rules: RuleFn>[]): Caster; map(transform: (value: Exclude) => D): Caster>>; default(defaultValue: T): Caster>; either(leftFactory: (error: TypeError) => Left, rightFactory: (value: T) => Right): CasterFn; validation(invalidFactory: (errors: ErrorMessage[]) => Invalid, validFactory: (value: T) => Valid): CasterFn; validate(value: unknown): ValidationResult; toBe(guard: (value: T) => value is S, typeName?: string): Caster; toBe(predicate: (value: T) => boolean, typeName?: string): Caster; } export interface StructCaster> extends Caster { partial: Caster>; } export type StructSchema> = { [field in keyof S]-?: CasterFn; }; export type Tuple = { [index in number]: any; }; export type TupleSchema = { [index in number]: CasterFn; }; type OptionalFields = { [field in keyof T]: undefined extends T[field] ? field : never; }[keyof T]; type RequiredFields = { [field in keyof T]: undefined extends T[field] ? never : field; }[keyof T]; type Resolve = { [field in keyof T]: T[field]; }; export type OptionalUndefined = Resolve<{ [key in OptionalFields]?: T[key]; } & { [key in RequiredFields]: T[key]; }>; export type Predicate = (value: T) => boolean; export type Guard = (value: T) => value is S;