UNPKG

veffect

Version:

powerful TypeScript validation library built on the robust foundation of Effect combining exceptional type safety, high performance, and developer experience. Taking inspiration from Effect's functional principles, VEffect delivers a balanced approach tha

424 lines 17.5 kB
/** * @since 1.0.0 */ import type * as Either from "./Either.js"; import type * as Option from "./Option.js"; import type { Pipeable } from "./Pipeable.js"; import * as Predicate from "./Predicate.js"; import type { Contravariant, Covariant, UnionToIntersection } from "./Types.js"; import type { Unify } from "./Unify.js"; /** * @category type ids * @since 1.0.0 */ export declare const MatcherTypeId: unique symbol; /** * @category type ids * @since 1.0.0 */ export type MatcherTypeId = typeof MatcherTypeId; /** * @category model * @since 1.0.0 */ export type Matcher<Input, Filters, RemainingApplied, Result, Provided> = TypeMatcher<Input, Filters, RemainingApplied, Result> | ValueMatcher<Input, Filters, RemainingApplied, Result, Provided>; /** * @category model * @since 1.0.0 */ export interface TypeMatcher<in Input, out Filters, out Remaining, out Result> extends Pipeable { readonly _tag: "TypeMatcher"; readonly [MatcherTypeId]: { readonly _input: Contravariant<Input>; readonly _filters: Covariant<Filters>; readonly _remaining: Covariant<Remaining>; readonly _result: Covariant<Result>; }; readonly cases: ReadonlyArray<Case>; add<I, R, RA, A>(_case: Case): TypeMatcher<I, R, RA, A>; } /** * @category model * @since 1.0.0 */ export interface ValueMatcher<in Input, Filters, out Remaining, out Result, Provided> extends Pipeable { readonly _tag: "ValueMatcher"; readonly [MatcherTypeId]: { readonly _input: Contravariant<Input>; readonly _filters: Covariant<Filters>; readonly _result: Covariant<Result>; }; readonly provided: Provided; readonly value: Either.Either<Provided, Remaining>; add<I, R, RA, A, Pr>(_case: Case): ValueMatcher<I, R, RA, A, Pr>; } /** * @category model * @since 1.0.0 */ export type Case = When | Not; /** * @category model * @since 1.0.0 */ export interface When { readonly _tag: "When"; guard(u: unknown): boolean; evaluate(input: unknown): any; } /** * @category model * @since 1.0.0 */ export interface Not { readonly _tag: "Not"; guard(u: unknown): boolean; evaluate(input: unknown): any; } /** * @category constructors * @since 1.0.0 */ export declare const type: <I>() => Matcher<I, Types.Without<never>, I, never, never>; /** * @category constructors * @since 1.0.0 */ export declare const value: <const I>(i: I) => Matcher<I, Types.Without<never>, I, never, I>; /** * @category constructors * @since 1.0.0 */ export declare const valueTags: <const I, P extends { readonly [Tag in Types.Tags<"_tag", I> & string]: (_: Extract<I, { readonly _tag: Tag; }>) => any; } & { readonly [Tag in Exclude<keyof P, Types.Tags<"_tag", I>>]: never; }>(fields: P) => (input: I) => Unify<ReturnType<P[keyof P]>>; /** * @category constructors * @since 1.0.0 */ export declare const typeTags: <I>() => <P extends { readonly [Tag in Types.Tags<"_tag", I> & string]: (_: Extract<I, { readonly _tag: Tag; }>) => any; } & { readonly [Tag in Exclude<keyof P, Types.Tags<"_tag", I>>]: never; }>(fields: P) => (input: I) => Unify<ReturnType<P[keyof P]>>; /** * @category combinators * @since 1.0.0 */ export declare const when: <R, const P extends Types.PatternPrimitive<R> | Types.PatternBase<R>, Fn extends (_: Types.WhenMatch<R, P>) => unknown>(pattern: P, f: Fn) => <I, F, A, Pr>(self: Matcher<I, F, R, A, Pr>) => Matcher<I, Types.AddWithout<F, Types.PForExclude<P>>, Types.ApplyFilters<I, Types.AddWithout<F, Types.PForExclude<P>>>, A | ReturnType<Fn>, Pr>; /** * @category combinators * @since 1.0.0 */ export declare const whenOr: <R, const P extends ReadonlyArray<Types.PatternPrimitive<R> | Types.PatternBase<R>>, Fn extends (_: Types.WhenMatch<R, P[number]>) => unknown>(...args: [...patterns: P, f: Fn]) => <I, F, A, Pr>(self: Matcher<I, F, R, A, Pr>) => Matcher<I, Types.AddWithout<F, Types.PForExclude<P[number]>>, Types.ApplyFilters<I, Types.AddWithout<F, Types.PForExclude<P[number]>>>, A | ReturnType<Fn>, Pr>; /** * @category combinators * @since 1.0.0 */ export declare const whenAnd: <R, const P extends ReadonlyArray<Types.PatternPrimitive<R> | Types.PatternBase<R>>, Fn extends (_: Types.WhenMatch<R, Types.ArrayToIntersection<P>>) => unknown>(...args: [...patterns: P, f: Fn]) => <I, F, A, Pr>(self: Matcher<I, F, R, A, Pr>) => Matcher<I, Types.AddWithout<F, Types.PForExclude<Types.ArrayToIntersection<P>>>, Types.ApplyFilters<I, Types.AddWithout<F, Types.PForExclude<Types.ArrayToIntersection<P>>>>, A | ReturnType<Fn>, Pr>; /** * @category combinators * @since 1.0.0 */ export declare const discriminator: <D extends string>(field: D) => <R, P extends Types.Tags<D, R> & string, B>(...pattern: [ first: P, ...values: Array<P>, f: (_: Extract<R, Record<D, P>>) => B ]) => <I, F, A, Pr>(self: Matcher<I, F, R, A, Pr>) => Matcher<I, Types.AddWithout<F, Extract<R, Record<D, P>>>, Types.ApplyFilters<I, Types.AddWithout<F, Extract<R, Record<D, P>>>>, B | A, Pr>; /** * @category combinators * @since 1.0.0 */ export declare const discriminatorStartsWith: <D extends string>(field: D) => <R, P extends string, B>(pattern: P, f: (_: Extract<R, Record<D, `${P}${string}`>>) => B) => <I, F, A, Pr>(self: Matcher<I, F, R, A, Pr>) => Matcher<I, Types.AddWithout<F, Extract<R, Record<D, `${P}${string}`>>>, Types.ApplyFilters<I, Types.AddWithout<F, Extract<R, Record<D, `${P}${string}`>>>>, B | A, Pr>; /** * @category combinators * @since 1.0.0 */ export declare const discriminators: <D extends string>(field: D) => <R, P extends { readonly [Tag in Types.Tags<D, R> & string]?: ((_: Extract<R, Record<D, Tag>>) => any) | undefined; } & { readonly [Tag in Exclude<keyof P, Types.Tags<D, R>>]: never; }>(fields: P) => <I, F, A, Pr>(self: Matcher<I, F, R, A, Pr>) => Matcher<I, Types.AddWithout<F, Extract<R, Record<D, keyof P>>>, Types.ApplyFilters<I, Types.AddWithout<F, Extract<R, Record<D, keyof P>>>>, A | ReturnType<P[keyof P] & {}>, Pr>; /** * @category combinators * @since 1.0.0 */ export declare const discriminatorsExhaustive: <D extends string>(field: D) => <R, P extends { readonly [Tag in Types.Tags<D, R> & string]: (_: Extract<R, Record<D, Tag>>) => any; } & { readonly [Tag in Exclude<keyof P, Types.Tags<D, R>>]: never; }>(fields: P) => <I, F, A, Pr>(self: Matcher<I, F, R, A, Pr>) => [Pr] extends [never] ? (u: I) => Unify<A | ReturnType<P[keyof P]>> : Unify<A | ReturnType<P[keyof P]>>; /** * @category combinators * @since 1.0.0 */ export declare const tag: <R, P extends Types.Tags<"_tag", R> & string, B>(...pattern: [ first: P, ...values: Array<P>, f: (_: Extract<R, Record<"_tag", P>>) => B ]) => <I, F, A, Pr>(self: Matcher<I, F, R, A, Pr>) => Matcher<I, Types.AddWithout<F, Extract<R, Record<"_tag", P>>>, Types.ApplyFilters<I, Types.AddWithout<F, Extract<R, Record<"_tag", P>>>>, B | A, Pr>; /** * @category combinators * @since 1.0.0 */ export declare const tagStartsWith: <R, P extends string, B>(pattern: P, f: (_: Extract<R, Record<"_tag", `${P}${string}`>>) => B) => <I, F, A, Pr>(self: Matcher<I, F, R, A, Pr>) => Matcher<I, Types.AddWithout<F, Extract<R, Record<"_tag", `${P}${string}`>>>, Types.ApplyFilters<I, Types.AddWithout<F, Extract<R, Record<"_tag", `${P}${string}`>>>>, B | A, Pr>; /** * @category combinators * @since 1.0.0 */ export declare const tags: <R, P extends { readonly [Tag in Types.Tags<"_tag", R> & string]?: ((_: Extract<R, Record<"_tag", Tag>>) => any) | undefined; } & { readonly [Tag in Exclude<keyof P, Types.Tags<"_tag", R>>]: never; }>(fields: P) => <I, F, A, Pr>(self: Matcher<I, F, R, A, Pr>) => Matcher<I, Types.AddWithout<F, Extract<R, Record<"_tag", keyof P>>>, Types.ApplyFilters<I, Types.AddWithout<F, Extract<R, Record<"_tag", keyof P>>>>, A | ReturnType<P[keyof P] & {}>, Pr>; /** * @category combinators * @since 1.0.0 */ export declare const tagsExhaustive: <R, P extends { readonly [Tag in Types.Tags<"_tag", R> & string]: (_: Extract<R, Record<"_tag", Tag>>) => any; } & { readonly [Tag in Exclude<keyof P, Types.Tags<"_tag", R>>]: never; }>(fields: P) => <I, F, A, Pr>(self: Matcher<I, F, R, A, Pr>) => [Pr] extends [never] ? (u: I) => Unify<A | ReturnType<P[keyof P]>> : Unify<A | ReturnType<P[keyof P]>>; /** * @category combinators * @since 1.0.0 */ export declare const not: <R, const P extends Types.PatternPrimitive<R> | Types.PatternBase<R>, Fn extends (_: Types.NotMatch<R, P>) => unknown>(pattern: P, f: Fn) => <I, F, A, Pr>(self: Matcher<I, F, R, A, Pr>) => Matcher<I, Types.AddOnly<F, Types.WhenMatch<R, P>>, Types.ApplyFilters<I, Types.AddOnly<F, Types.WhenMatch<R, P>>>, A | ReturnType<Fn>, Pr>; /** * @category predicates * @since 1.0.0 */ export declare const nonEmptyString: SafeRefinement<string, never>; /** * @category predicates * @since 1.0.0 */ export declare const is: <Literals extends ReadonlyArray<string | number | bigint | boolean | null>>(...literals: Literals) => Predicate.Refinement<unknown, Literals[number]>; /** * @category predicates * @since 1.0.0 */ export declare const string: Predicate.Refinement<unknown, string>; /** * @category predicates * @since 1.0.0 */ export declare const number: Predicate.Refinement<unknown, number>; /** * @category predicates * @since 1.0.0 */ export declare const any: SafeRefinement<unknown, any>; /** * @category predicates * @since 1.0.0 */ export declare const defined: <A>(u: A) => u is A & {}; /** * @category predicates * @since 1.0.0 */ export declare const boolean: Predicate.Refinement<unknown, boolean>; declare const _undefined: Predicate.Refinement<unknown, undefined>; export { /** * @category predicates * @since 1.0.0 */ _undefined as undefined }; declare const _null: Predicate.Refinement<unknown, null>; export { /** * @category predicates * @since 1.0.0 */ _null as null }; /** * @category predicates * @since 1.0.0 */ export declare const bigint: Predicate.Refinement<unknown, bigint>; /** * @category predicates * @since 1.0.0 */ export declare const symbol: Predicate.Refinement<unknown, symbol>; /** * @category predicates * @since 1.0.0 */ export declare const date: Predicate.Refinement<unknown, Date>; /** * @category predicates * @since 1.0.0 */ export declare const record: Predicate.Refinement<unknown, { [x: string | symbol]: unknown; }>; /** * @category predicates * @since 1.0.0 */ export declare const instanceOf: <A extends abstract new (...args: any) => any>(constructor: A) => SafeRefinement<InstanceType<A>, never>; /** * @category predicates * @since 1.0.0 */ export declare const instanceOfUnsafe: <A extends abstract new (...args: any) => any>(constructor: A) => SafeRefinement<InstanceType<A>, InstanceType<A>>; /** * @category conversions * @since 1.0.0 */ export declare const orElse: <RA, B>(f: (b: RA) => B) => <I, R, A, Pr>(self: Matcher<I, R, RA, A, Pr>) => [Pr] extends [never] ? (input: I) => Unify<B | A> : Unify<B | A>; /** * @category conversions * @since 1.0.0 */ export declare const orElseAbsurd: <I, R, RA, A, Pr>(self: Matcher<I, R, RA, A, Pr>) => [Pr] extends [never] ? (input: I) => Unify<A> : Unify<A>; /** * @category conversions * @since 1.0.0 */ export declare const either: <I, F, R, A, Pr>(self: Matcher<I, F, R, A, Pr>) => [Pr] extends [never] ? (input: I) => Either.Either<Unify<A>, R> : Either.Either<Unify<A>, R>; /** * @category conversions * @since 1.0.0 */ export declare const option: <I, F, R, A, Pr>(self: Matcher<I, F, R, A, Pr>) => [Pr] extends [never] ? (input: I) => Option.Option<Unify<A>> : Option.Option<Unify<A>>; /** * @category conversions * @since 1.0.0 */ export declare const exhaustive: <I, F, A, Pr>(self: Matcher<I, F, never, A, Pr>) => [Pr] extends [never] ? (u: I) => Unify<A> : Unify<A>; /** * @since 1.0.0 * @category type ids */ export declare const SafeRefinementId: unique symbol; /** * @since 1.0.0 * @category type ids */ export type SafeRefinementId = typeof SafeRefinementId; /** * @category model * @since 1.0.0 */ export interface SafeRefinement<in A, out R = A> { readonly [SafeRefinementId]: (a: A) => R; } declare const Fail: unique symbol; type Fail = typeof Fail; /** * @since 1.0.0 */ export declare namespace Types { /** * @since 1.0.0 */ type WhenMatch<R, P> = [ 0 ] extends [1 & R] ? PForMatch<P> : P extends SafeRefinement<infer SP, never> ? SP : P extends Predicate.Refinement<infer _R, infer RP> ? [Extract<R, RP>] extends [infer X] ? [X] extends [never] ? RP : X : never : P extends PredicateA<infer PP> ? PP : ExtractMatch<R, PForMatch<P>>; /** * @since 1.0.0 */ type NotMatch<R, P> = Exclude<R, ExtractMatch<R, PForExclude<P>>>; /** * @since 1.0.0 */ type PForMatch<P> = [SafeRefinementP<ResolvePred<P>>] extends [infer X] ? X : never; /** * @since 1.0.0 */ type PForExclude<P> = [SafeRefinementR<ToSafeRefinement<P>>] extends [infer X] ? X : never; type PredicateA<A> = Predicate.Predicate<A> | Predicate.Refinement<A, A>; type SafeRefinementP<A> = A extends never ? never : A extends SafeRefinement<infer S, infer _> ? S : A extends Function ? A : A extends Record<string, any> ? { [K in keyof A]: SafeRefinementP<A[K]>; } : A; type SafeRefinementR<A> = A extends never ? never : A extends SafeRefinement<infer _, infer R> ? R : A extends Function ? A : A extends Record<string, any> ? { [K in keyof A]: SafeRefinementR<A[K]>; } : A; type ResolvePred<A> = A extends never ? never : A extends Predicate.Refinement<any, infer P> ? P : A extends Predicate.Predicate<infer P> ? P : A extends SafeRefinement<any> ? A : A extends Record<string, any> ? { [K in keyof A]: ResolvePred<A[K]>; } : A; type ToSafeRefinement<A> = A extends never ? never : A extends Predicate.Refinement<any, infer P> ? SafeRefinement<P, P> : A extends Predicate.Predicate<infer P> ? SafeRefinement<P, never> : A extends SafeRefinement<any> ? A : A extends Record<string, any> ? { [K in keyof A]: ToSafeRefinement<A[K]>; } : NonLiteralsTo<A, never>; type NonLiteralsTo<A, T> = [A] extends [string | number | boolean | bigint] ? [string] extends [A] ? T : [number] extends [A] ? T : [boolean] extends [A] ? T : [bigint] extends [A] ? T : A : A; /** * @since 1.0.0 */ type PatternBase<A> = A extends ReadonlyArray<infer _T> ? ReadonlyArray<any> | PatternPrimitive<A> : A extends Record<string, any> ? Partial<{ [K in keyof A]: PatternPrimitive<A[K] & {}> | PatternBase<A[K] & {}>; }> : never; /** * @since 1.0.0 */ type PatternPrimitive<A> = PredicateA<A> | A | SafeRefinement<any>; /** * @since 1.0.0 */ interface Without<out X> { readonly _tag: "Without"; readonly _X: X; } /** * @since 1.0.0 */ interface Only<out X> { readonly _tag: "Only"; readonly _X: X; } /** * @since 1.0.0 */ type AddWithout<A, X> = [A] extends [Without<infer WX>] ? Without<X | WX> : [A] extends [Only<infer OX>] ? Only<Exclude<OX, X>> : never; /** * @since 1.0.0 */ type AddOnly<A, X> = [A] extends [Without<infer WX>] ? [X] extends [WX] ? never : Only<X> : [A] extends [Only<infer OX>] ? [X] extends [OX] ? Only<X> : never : never; /** * @since 1.0.0 */ type ApplyFilters<I, A> = A extends Only<infer X> ? X : A extends Without<infer X> ? Exclude<I, X> : never; /** * @since 1.0.0 */ type Tags<D extends string, P> = P extends Record<D, infer X> ? X : never; /** * @since 1.0.0 */ type ArrayToIntersection<A extends ReadonlyArray<any>> = UnionToIntersection<A[number]>; /** * @since 1.0.0 */ type ExtractMatch<I, P> = [ExtractAndNarrow<I, P>] extends [infer EI] ? EI : never; type Replace<A, B> = A extends Function ? A : A extends Record<string | number, any> ? { [K in keyof A]: K extends keyof B ? Replace<A[K], B[K]> : A[K]; } : [B] extends [A] ? B : A; type MaybeReplace<I, P> = [P] extends [I] ? P : [I] extends [P] ? Replace<I, P> : Fail; type BuiltInObjects = Function | Date | RegExp | Generator | { readonly [Symbol.toStringTag]: string; }; type IsPlainObject<T> = T extends BuiltInObjects ? false : T extends Record<string, any> ? true : false; type Simplify<A> = { [K in keyof A]: A[K]; } & {}; type ExtractAndNarrow<Input, P> = unknown extends P ? Input : Input extends infer I ? Exclude<I extends ReadonlyArray<any> ? P extends ReadonlyArray<any> ? { readonly [K in keyof I]: K extends keyof P ? ExtractAndNarrow<I[K], P[K]> : I[K]; } extends infer R ? Fail extends R[keyof R] ? never : R : never : never : IsPlainObject<I> extends true ? string extends keyof I ? I extends P ? I : never : symbol extends keyof I ? I extends P ? I : never : Simplify<{ [RK in Extract<keyof I, keyof P>]-?: ExtractAndNarrow<I[RK], P[RK]>; } & Omit<I, keyof P>> extends infer R ? [keyof P] extends [keyof RemoveFails<R>] ? R : never : never : MaybeReplace<I, P> extends infer R ? [I] extends [R] ? I : R : never, Fail> : never; type RemoveFails<A> = NonFailKeys<A> extends infer K ? [K] extends [keyof A] ? { [RK in K]: A[RK]; } : {} : {}; type NonFailKeys<A> = keyof A & {} extends infer K ? K extends keyof A ? A[K] extends Fail ? never : K : never : never; } //# sourceMappingURL=Match.d.ts.map