/** * Fluent, callable predicate combinators that preserve TypeScript type guards. * * A Predicate is: * - Callable as `(value: T) => value is U` * - Composable through `.and()`, `.or()`, and `.negate()` * * Ordinary boolean predicates are treated as narrowing to `T`, meaning they * do not narrow the input type by themselves. Composed predicates passed to * `.and()` / `.or()` may return any value; they are tested for truthiness. * * @module */ /** An ordinary boolean predicate. */ export type PredicateFunction = (value: T) => boolean; /** A predicate that narrows T to U. */ export type TypePredicateFunction = (value: T) => value is U; /** A predicate tested for truthiness when composed with `.and()` / `.or()`. */ export type PredicateInput = (value: T) => unknown; /** * Extracts the narrowed type from a type predicate. * * Ordinary boolean predicates do not narrow, so they produce T. A guard whose * narrowed type is disjoint from T (`Extract` is `never`) is treated as a * non-narrowing filter and keeps T, rather than collapsing the chain to `never` - * this is what a negated narrowing guard looks like (e.g. `hasName(...).negate()`, * which widens back to a supertype of T). */ type NarrowedBy = P extends (value: any) => value is infer U ? [Extract] extends [never] ? T : Extract : T; /** Intersects the narrowed types produced by a tuple of predicates. */ type AndNarrowed[], Result = T> = P extends readonly [ infer First, ...infer Rest extends readonly PredicateInput[] ] ? AndNarrowed> : Result; /** Unions the narrowed types produced by a tuple of predicates. */ type OrNarrowed[], Result = never> = P extends readonly [ infer First, ...infer Rest extends readonly PredicateInput[] ] ? OrNarrowed> : Result; /** * A callable predicate with fluent composition methods. * * T is the accepted input type. * U is the type established when the predicate returns true. */ export interface Predicate { (value: T): value is U; /** * Returns a predicate requiring this predicate and every supplied predicate * to match. * * Type guards are intersected. Additional predicates are checked against the * type already established by this predicate. */ and[]>(...predicates: P): Predicate, T>>; /** * Returns a predicate requiring this predicate or any supplied predicate * to match. * * Type guards are unioned. Because an ordinary boolean predicate could * accept any value of `U`, including one causes the resulting predicate to * narrow only to `U`. */ or[]>(...predicates: P): Predicate, T>>; /** * Returns the logical inverse of this predicate. * * For a type predicate narrowing T to U, the result narrows to * Exclude. */ negate(): Predicate>; } /** * Wraps a type predicate while preserving its narrowed type. */ export declare function create(predicate: TypePredicateFunction): Predicate; /** * Wraps an ordinary boolean or truthy predicate. */ export declare function create(predicate: PredicateInput): Predicate; export {};