import { Narrower, UnNarrow } from './schema';
/**
 * Creates a function from a narrower schema that can be reused to narrow objects.
 * This simple closure can be used when a whole Guard instance would be too much.
 *
 * @example
 * import { satisfier } from 'narrow-minded'
 * const satisfies = satisfier(['string', 'number'])
 * satisfies(['horse', 42]) // => true
 */
export declare const satisfier: <N extends Narrower>(n: N) => (u: unknown) => u is UnNarrow<N>;
export type NarrowingFunction<P> = (u: unknown) => u is P;
export type Payload<G> = G extends Guard<infer P> ? P : unknown;
export declare class Guard<P> {
    /**
     * Creates a new guard that uses a `narrow` function.
     * A little shortcut for `new Guard(narrow(...))`.
     * @example
     *
     * import { Guard } from 'narrow-minded'
     * const myGuard = Guard.narrow(['string', 'number'])
     * myGuard.satisfied(['horse', 42]) // => true
     *
     * @param n Narrower
     * @returns Guard
     */
    static narrow<N extends Narrower>(n: N): Guard<UnNarrow<N>>;
    readonly NF: NarrowingFunction<P>;
    constructor(NF: NarrowingFunction<P>);
    /**
     * Runs the guard's narrowing function to validate the unknown value's type.
     * Operates as a type predicate so conditional blocks infer this structure.
     * @example
     *
     * const myGuard = Guard.narrow({
     * 	name: 'string',
     * 	values: ['number'],
     * })
     *
     * const good: unknown = { name: 'Horse', values: [1, 2] }
     * if (myGuard.satisfied(good)) {
     * 	console.log('Good ' + good.name)
     * 	// => 'Good Horse'
     * }
     *
     * const bad: unknown = { name: 42, values: 'Nope' }
     * if (!myGuard.satisfied(bad)) {
     * 	console.log('Bad ')
     * 	// => 'Bad'
     * }
     *
     * @param u The unknown value.
     * @returns A type predicate that `u` satisfies this guard.
     */
    satisfied(u: unknown): u is P;
    /**
     * An identity function that returns the value passed to it. Useful for
     * defining objects that satisfy this guard using type inference.
     * @param p
     * @returns p
     */
    build(p: P): P;
    /**
     * Creates a new guard that will satisfy the constraints of `this` AND `other`.
     * Useful for combining primitive narrows with more complex type checking.
     * @example
     * const myGuard = Guard.narrow({ type: 'string' }).and(
     * 	(u: unknown): u is { type: 'this' | 'that' } =>
     * 		['this', 'that'].includes((u as any).type),
     * )
     *
     * @param other - Another Guard or a Narrower/NarrowerFunction which will
     * be wrapped into a Guard automatically.
     * @return Guard
     */
    and<N extends Narrower>(other: N): Guard<P & UnNarrow<N>>;
    and<P2>(other: Guard<P2> | NarrowingFunction<P2>): Guard<P & P2>;
}
/**
 * A singleton that can be used to build `and` chains.
 * @example
 * if (unknown.and('string').satisfied('Great')) {
 * 	console.log('Great')
 * }
 */
export declare const unknown: Guard<unknown>;
//# sourceMappingURL=guard.d.ts.map