import { Result } from "./result"; import { RuntimeType } from "./issues/shared"; import type { Kind, TypedKind } from "./kind"; export type Projection = { readonly kind: "none"; } | { readonly kind: "structural"; readonly value: T; } | { readonly kind: "opaque"; readonly value: T; }; export type ProjectionKind = Projection["kind"]; export declare abstract class Type { readonly _type: T; abstract check(val: any): Result; abstract sliceResult(val: any): Result; assert(val: any): T; slice(val: any): T; /** * Use as a type guard. * * @example * const FooChecker: t.Type = ... * if (FooChecker.guard(val)) { * // in this scope, val has type T * } */ guard(val: any): val is T; /** * Typescript helper that enforces the correct declaration of a value with no * overhead. * * @example * const User = t.subtype({ name: t.str, email: t.str }) * const myUser = User.({ dog: 'cow' }) // Typescript compile error */ literal(val: T): T; and(r: Type): Type; or(r: Type): Either; validate(desc: string, fn: Validator): Type; comment(comment: string): Comment; } export declare abstract class TypeImpl extends Type { protected abstract merge(type: TypedKind): TypedKind | undefined; protected abstract project(val: any): Projection; protected projectionOf(type: TypeImpl, val: any): Projection; and(r: Type): Type; } export declare abstract class UnmergeableType extends TypeImpl { sliceResult(val: any): Result; protected merge(_: TypedKind): TypedKind | undefined; } export declare abstract class ConstraintType extends UnmergeableType { protected project(_: any): Projection; } export declare abstract class OpaqueType extends UnmergeableType { protected project(val: any): Projection; } export declare class Comment extends TypeImpl { readonly commentStr: string; readonly wrapped: TypedKind; constructor(commentStr: string, wrapped: Type); check(val: any): Result; sliceResult(val: any): Result; protected merge(type: TypedKind): TypedKind; protected project(val: any): Projection; } export type Validator = (val: T) => boolean; export type ValidationIssue = { readonly kind: "validation"; readonly description: string; readonly threw: boolean; readonly subject: RuntimeType; }; export declare class Validation extends ConstraintType { readonly desc: string; readonly validator: Validator; constructor(desc: string, fn: Validator); check(val: any): Result; } export declare class Either extends TypeImpl { readonly l: TypedKind; readonly r: TypedKind; constructor(l: Type, r: Type); check(val: any): Result; sliceResult(val: any): Result; protected merge(type: TypedKind): TypedKind<(L | R) & Incoming>; protected project(val: any): Projection; } export declare class Intersection extends TypeImpl { readonly operands: ReadonlyArray; constructor(operands: ReadonlyArray); check(val: any): Result; sliceResult(val: any): Result; protected merge(type: TypedKind): TypedKind; protected project(val: any): Projection; }