import { $ } from "./expect-utils";
export declare type _<check extends true> = never;
export declare namespace _ {
    type pass<condition extends true> = never;
    type fail<condition extends false> = never;
    type falsy = $.falsy;
    type primitive = $.primitive;
    type nullish = $.nullish;
}
declare type tag<target, //
key extends string> = target & Record<`--${key}`, key>;
declare type data<target, //
key extends string, value> = target & Record<`::${key}`, value>;
declare type wrap<T> = [T];
declare type unwrap<T> = T extends [infer U] ? U : T;
declare type check<value, //
type extends __checkType> = data<wrap<value>, "check", type>;
declare type negativeCheck<T extends check<any, any>> = tag<T, "not">;
declare type checksMap<given, expected> = {
    falsy: $.isFalsy<given>;
    truthy: $.isTruthy<given>;
    defined: $.isDefined<given>;
    optional: $.isOptional<given>;
    nullish: $.isAnyAssignable<$.nullish, given>;
    primitive: $.isPrimitive<given>;
    invokable: $.isInvokable<given>;
    newable: $.isNewable<given>;
    literal: $.isLiteral<given>;
    never: $.isNever<given>;
    assign: $.isAssignable<given, expected>;
    accept: $.isAssignable<expected, given>;
    equal: $.equals<given, expected>;
    extend: $.doesExtend<given, expected>;
    extendedBy: $.doesExtend<expected, given>;
    prefixed: $.isPrefixed<given, expected>;
    suffixed: $.isSuffixed<given, expected>;
    contains: $.doesContain<given, expected>;
    includes: $.includes<given, expected>;
    hasKeys: $.hasKeys<given, expected>;
    hasOnlyKeys: $.hasOnlyKeys<given, expected>;
    hasValues: $.hasValues<given, expected>;
    hasOnlyValues: $.hasOnlyValues<given, expected>;
    returns: $.returns<given, expected>;
    returnsOnly: $.returnsOnly<given, expected>;
    resolvesTo: $.resolvesTo<given, expected>;
    resolvesOnlyTo: $.resolvesOnlyTo<given, expected>;
    parameters: $.acceptsParameters<given, expected>;
    parametersOnly: $.acceptsOnlyParameters<given, expected>;
};
export declare type __checkType = keyof checksMap<any, any>;
export declare namespace to {
    type equalTo<T> = check<T, "equal">;
    type be<T> = check<T, "equal">;
    type accept<T> = check<T, "accept">;
    type beAssignableTo<T> = check<T, "assign">;
    type extend<T> = check<T, "extend">;
    type beExtendedBy<T> = check<T, "extendedBy">;
    type beDefined = check<unknown, "defined">;
    type beOptional = check<unknown, "optional">;
    type beNullish = check<unknown, "nullish">;
    type bePrimitive = check<unknown, "primitive">;
    type beLiteral = check<unknown, "literal">;
    type beNever = check<unknown, "never">;
    type beTruthy = check<unknown, "truthy">;
    type beFalsy = check<unknown, "falsy">;
    type beInvocable = check<unknown, "invokable">;
    type beNewable = check<unknown, "newable">;
    type startWith<T extends string> = check<T, "prefixed">;
    type endWith<T extends string> = check<T, "suffixed">;
    type contain<T extends string> = check<T, "contains">;
    type haveKeys<T extends string> = check<T, "hasKeys">;
    type haveOnlyKeys<T extends string> = check<T, "hasOnlyKeys">;
    type haveFieldsThatAccept<T> = check<T, "hasValues">;
    type haveFieldsThatAcceptOnly<T> = check<T, "hasOnlyValues">;
    type include<T> = check<T, "includes">;
    type returnType<T> = check<T, "returns">;
    type returnOnly<T> = check<T, "returnsOnly">;
    type resolveTo<T> = check<T, "resolvesTo">;
    type resolveToOnly<T> = check<T, "resolvesOnlyTo">;
    type acceptParameters<T extends any[]> = check<T, "parameters">;
    type acceptOnlyParameters<T extends any[]> = check<T, "parametersOnly">;
    namespace not {
        type beTruthy = negativeCheck<to.beTruthy>;
        type beFalsy = negativeCheck<to.beFalsy>;
        type beDefined = negativeCheck<to.beDefined>;
        type beOptional = negativeCheck<to.beOptional>;
        type beNullish = negativeCheck<to.beNullish>;
        type beInvocable = negativeCheck<to.beInvocable>;
        type beNewable = negativeCheck<to.beNewable>;
        type bePrimitive = negativeCheck<to.bePrimitive>;
        type beLiteral = negativeCheck<to.beLiteral>;
        type beNever = negativeCheck<to.beNever>;
        type startWith<T extends string> = negativeCheck<to.startWith<T>>;
        type endWith<T extends string> = negativeCheck<to.endWith<T>>;
        type contain<T extends string> = negativeCheck<to.contain<T>>;
        type accept<T> = negativeCheck<to.accept<T>>;
        type beAssignableTo<T> = negativeCheck<to.beAssignableTo<T>>;
        type extend<T> = negativeCheck<to.extend<T>>;
        type beExtendedBy<T> = negativeCheck<to.beExtendedBy<T>>;
        type equalTo<T> = negativeCheck<to.equalTo<T>>;
        type be<T> = negativeCheck<to.be<T>>;
        type include<T> = negativeCheck<to.include<T>>;
        type haveKeys<T extends string> = negativeCheck<to.haveKeys<T>>;
        type haveOnlyKeys<T extends string> = negativeCheck<to.haveOnlyKeys<T>>;
        type haveFieldsThatAccept<T> = negativeCheck<to.haveFieldsThatAccept<T>>;
        type haveFieldsThatAcceptOnly<T> = negativeCheck<to.haveFieldsThatAcceptOnly<T>>;
        type returnType<T> = negativeCheck<to.returnType<T>>;
        type returnOnly<T> = negativeCheck<to.returnOnly<T>>;
        type resolveTo<T> = negativeCheck<to.resolveTo<T>>;
        type resolveToOnly<T> = negativeCheck<to.resolveToOnly<T>>;
        type acceptParameters<T extends any[]> = negativeCheck<to.acceptParameters<T>>;
        type acceptOnlyParameters<T extends any[]> = negativeCheck<to.acceptOnlyParameters<T>>;
    }
}
declare type unwrapNegativeCheck<T extends check<any, any>> = [T] extends [negativeCheck<infer _check>] ? _check extends check<any, any> ? _check : never : T;
declare type extractCheckData<T extends check<any, any>> = [
    T
] extends [data<infer value, "check", infer type>] ? [value] extends [data<infer _value, "check", type>] ? [unwrap<_value>, type] : never : never;
declare type resolveCheck<given, //
expected, check extends __checkType> = {
    [key in check]: checksMap<given, expected>[key];
}[check];
declare type _expect<given, //
payload extends check<any, __checkType>, payloadValue extends check<any, any> = unwrapNegativeCheck<payload>, negativeCheck extends boolean = $.notEquals<payload, payloadValue>, data extends [any, any] = extractCheckData<payloadValue>, result extends boolean = resolveCheck<given, data[0], data[1]>> = $.ifElse<negativeCheck, $.not<result>, result>;
export declare type expect<given, //
expectation extends check<any, __checkType>> = _expect<given, expectation>;
export declare type expectReturnOf<given extends (...args: any[]) => any, expectation extends check<any, __checkType>> = _expect<ReturnType<given>, expectation>;
export declare type expectParametersOf<given extends (...args: any[]) => any, expectation extends check<any, __checkType>> = _expect<Parameters<given>, expectation>;
export declare type expectKeysOf<given extends object, payload extends check<any, __checkType>> = _expect<keyof given, payload>;
export declare type expectValuesOf<given extends {
    [key: keyof any]: any;
} | Array<any>, payload extends check<any, __checkType>> = given extends Array<any> ? _expect<given[number], payload> : _expect<given[keyof given], payload>;
export declare type expectFieldOf<given extends {
    [key: keyof any]: any;
} | Array<any>, field extends keyof given, payload extends check<any, __checkType>> = _expect<given[field], payload>;
export declare function suit(description: string, context: (...ctx: any[]) => any): void;
export declare function test(name: string, context: (...ctx: any[]) => any): void;
export {};
