/** A standard selector function, which takes three generic type arguments:
 * @param State The first value, often a Redux root state object
 * @param Result The final result returned by the selector
 * @param Params All additional arguments passed into the selector
 */
export declare type Selector<State = any, Result = unknown, Params extends never | readonly any[] = any[]> = [Params] extends [never] ? (state: State) => Result : (state: State, ...params: Params) => Result;
/** Selectors generated by Reselect have several additional fields attached: */
export interface OutputSelectorFields<Combiner extends UnknownFunction> {
    /** The final function passed to `createSelector` */
    resultFunc: Combiner;
    /** The same function, memoized */
    memoizedResultFunc: Combiner;
    /** Returns the last result calculated by the selector */
    lastResult: () => ReturnType<Combiner>;
    /** An array of the input selectors */
    dependencies: SelectorArray;
    /** Counts the number of times the output has been recalculated */
    recomputations: () => number;
    /** Resets the count of recomputations count to 0 */
    resetRecomputations: () => number;
}
/** Represents the actual selectors generated by `createSelector`.
 * The selector is:
 * - "a function that takes this state + params and returns a result"
 * - plus the attached additional fields
 */
export declare type OutputSelector<S extends SelectorArray, Result, Combiner extends UnknownFunction, Params extends readonly any[] = never> = Selector<GetStateFromSelectors<S>, Result, Params> & OutputSelectorFields<Combiner>;
/** A selector that is assumed to have one additional argument, such as
 * the props from a React component
 */
export declare type ParametricSelector<State, Props, Result> = Selector<State, Result, [
    Props,
    ...any
]>;
/** A generated selector that is assumed to have one additional argument */
export declare type OutputParametricSelector<State, Props, Result, Combiner extends UnknownFunction> = ParametricSelector<State, Props, Result> & OutputSelectorFields<Combiner>;
/** An array of input selectors */
export declare type SelectorArray = ReadonlyArray<Selector>;
/** A standard function returning true if two values are considered equal */
export declare type EqualityFn = (a: any, b: any) => boolean;
/** Extracts an array of all return types from all input selectors */
export declare type SelectorResultArray<Selectors extends SelectorArray> = ExtractReturnType<Selectors>;
/** Determines the combined single "State" type (first arg) from all input selectors */
export declare type GetStateFromSelectors<S extends SelectorArray> = MergeParameters<S>[0];
/** Determines the combined  "Params" type (all remaining args) from all input selectors */
export declare type GetParamsFromSelectors<S extends SelectorArray, RemainingItems extends readonly unknown[] = Tail<MergeParameters<S>>> = RemainingItems extends [EmptyObject] ? never : RemainingItems;
/** Given a set of input selectors, extracts the intersected parameters to determine
 * what values can actually be passed to all of the input selectors at once
 * WARNING: "you are not expected to understand this" :)
 */
export declare type MergeParameters<T extends readonly UnknownFunction[], ParamsArrays extends readonly any[][] = ExtractParams<T>, TransposedArrays = Transpose<ParamsArrays>, TuplifiedArrays extends any[] = TuplifyUnion<TransposedArrays>, LongestParamsArray extends readonly any[] = LongestArray<TuplifiedArrays>> = ExpandItems<RemoveNames<{
    [index in keyof LongestParamsArray]: LongestParamsArray[index] extends LongestParamsArray[number] ? IgnoreInvalidIntersections<IntersectAll<LongestParamsArray[index]>> : never;
}>>;
/** Any function with arguments */
export declare type UnknownFunction = (...args: any[]) => any;
/** An object with no fields */
declare type EmptyObject = {
    [K in any]: never;
};
declare type IgnoreInvalidIntersections<T> = T extends EmptyObject ? never : T;
/** Extract the parameters from all functions as a tuple */
export declare type ExtractParams<T extends readonly UnknownFunction[]> = {
    [index in keyof T]: T[index] extends T[number] ? Parameters<T[index]> : never;
};
/** Extract the return type from all functions as a tuple */
export declare type ExtractReturnType<T extends readonly UnknownFunction[]> = {
    [index in keyof T]: T[index] extends T[number] ? ReturnType<T[index]> : never;
};
/** Recursively expand all fields in an object for easier reading */
export declare type ExpandItems<T extends readonly unknown[]> = {
    [index in keyof T]: T[index] extends T[number] ? Expand<T[index]> : never;
};
/** First item in an array */
export declare type Head<T> = T extends [any, ...any[]] ? T[0] : never;
/** All other items in an array */
export declare type Tail<A> = A extends [any, ...infer Rest] ? Rest : never;
/** Extract only numeric keys from an array type */
export declare type AllArrayKeys<A extends readonly any[]> = A extends any ? {
    [K in keyof A]: K;
}[number] : never;
export declare type List<A = any> = ReadonlyArray<A>;
export declare type Has<U, U1> = [U1] extends [U] ? 1 : 0;
/** Select the longer of two arrays */
export declare type Longest<L extends List, L1 extends List> = L extends unknown ? L1 extends unknown ? {
    0: L1;
    1: L;
}[Has<keyof L, keyof L1>] : never : never;
/** Recurse over a nested array to locate the longest one.
 * Acts like a type-level `reduce()`
 */
export declare type LongestArray<S extends readonly any[][]> = IsTuple<S> extends '0' ? S[0] : S extends [any[], any[]] ? Longest<S[0], S[1]> : S extends [any[], any[], ...infer Rest] ? Longest<Longest<S[0], S[1]>, Rest extends any[][] ? LongestArray<Rest> : []> : S extends [any[]] ? S[0] : never;
/** Recursive type for intersecting together all items in a tuple, to determine
 *  the final parameter type at a given argument index in the generated selector. */
export declare type IntersectAll<T extends any[]> = IsTuple<T> extends '0' ? T[0] : _IntersectAll<T>;
declare type IfJustNullish<T, True, False> = [T] extends [undefined | null] ? True : False;
/** Intersect a pair of types together, for use in parameter type calculation.
 * This is made much more complex because we need to correctly handle cases
 * where a function has fewer parameters and the type is `undefined`, as well as
 * optional params or params that have `null` or `undefined` as part of a union.
 *
 * If the next type by itself is `null` or `undefined`, we exclude it and return
 * the other type. Otherwise, intersect them together.
 */
declare type _IntersectAll<T, R = unknown> = T extends [infer First, ...infer Rest] ? _IntersectAll<Rest, IfJustNullish<First, R, R & First>> : R;
/** The infamous "convert a union type to an intersection type" hack
 * Source: https://github.com/sindresorhus/type-fest/blob/main/source/union-to-intersection.d.ts
 * Reference: https://github.com/microsoft/TypeScript/issues/29594
 */
export declare type UnionToIntersection<Union> = (Union extends unknown ? (distributedUnion: Union) => void : never) extends (mergedIntersection: infer Intersection) => void ? Intersection : never;
/**
 * Removes field names from a tuple
 * Source: https://stackoverflow.com/a/63571175/62937
 */
declare type RemoveNames<T extends readonly any[]> = [any, ...T] extends [
    any,
    ...infer U
] ? U : never;
/**
 * Assorted util types for type-level conditional logic
 * Source: https://github.com/KiaraGrouwstra/typical
 */
export declare type Bool = '0' | '1';
export declare type Obj<T> = {
    [k: string]: T;
};
export declare type And<A extends Bool, B extends Bool> = ({
    1: {
        1: '1';
    } & Obj<'0'>;
} & Obj<Obj<'0'>>)[A][B];
export declare type Matches<V, T> = V extends T ? '1' : '0';
export declare type IsArrayType<T> = Matches<T, any[]>;
export declare type Not<T extends Bool> = {
    '1': '0';
    '0': '1';
}[T];
export declare type InstanceOf<V, T> = And<Matches<V, T>, Not<Matches<T, V>>>;
export declare type IsTuple<T extends {
    length: number;
}> = And<IsArrayType<T>, InstanceOf<T['length'], number>>;
/**
 * Code to convert a union of values into a tuple.
 * Source: https://stackoverflow.com/a/55128956/62937
 */
declare type Push<T extends any[], V> = [...T, V];
declare type LastOf<T> = UnionToIntersection<T extends any ? () => T : never> extends () => infer R ? R : never;
declare type TuplifyUnion<T, L = LastOf<T>, N = [T] extends [never] ? true : false> = true extends N ? [] : Push<TuplifyUnion<Exclude<T, L>>, L>;
/**
 * Converts "the values of an object" into a tuple, like a type-level `Object.values()`
 * Source: https://stackoverflow.com/a/68695508/62937
 */
export declare type ObjValueTuple<T, KS extends any[] = TuplifyUnion<keyof T>, R extends any[] = []> = KS extends [infer K, ...infer KT] ? ObjValueTuple<T, KT, [...R, T[K & keyof T]]> : R;
/**
 * Transposes nested arrays
 * Source: https://stackoverflow.com/a/66303933/62937
 */
declare type Transpose<T> = T[Extract<keyof T, T extends readonly any[] ? number : unknown>] extends infer V ? {
    [K in keyof V]: {
        [L in keyof T]: K extends keyof T[L] ? T[L][K] : undefined;
    };
} : never;
/** Utility type to infer the type of "all params of a function except the first", so we can determine what arguments a memoize function accepts */
export declare type DropFirst<T extends unknown[]> = T extends [unknown, ...infer U] ? U : never;
/**
 * Expand an item a single level, or recursively.
 * Source: https://stackoverflow.com/a/69288824/62937
 */
export declare type Expand<T> = T extends (...args: infer A) => infer R ? (...args: Expand<A>) => Expand<R> : T extends infer O ? {
    [K in keyof O]: O[K];
} : never;
export declare type ExpandRecursively<T> = T extends (...args: infer A) => infer R ? (...args: ExpandRecursively<A>) => ExpandRecursively<R> : T extends object ? T extends infer O ? {
    [K in keyof O]: ExpandRecursively<O[K]>;
} : never : T;
declare type Identity<T> = T;
/**
 * Another form of type value expansion
 * Source: https://github.com/microsoft/TypeScript/issues/35247
 */
export declare type Mapped<T> = Identity<{
    [k in keyof T]: T[k];
}>;
export declare type If2<B extends Boolean2, Then, Else = never> = B extends 1 ? Then : Else;
export declare type Boolean2 = 0 | 1;
export declare type Key = string | number | symbol;
export declare type BuiltIn = Function | Error | Date | {
    readonly [Symbol.toStringTag]: string;
} | RegExp | Generator;
export {};
