import type { CreateSelectorOptions } from 'reselect';
import type {
  Path,
  ComputeValue,
  IdentitySelector,
  StandardSelector,
  PathStructured,
  ComputeStructuredValue,
  IdentityStructuredSelector,
} from './internalTypes.d.cts';
/**
 * Create a selector without any boilerplate code
 *
 * @example
 * import type { createSelector } from 'selectorator';
 *
 * interface Item {
 *   name: string;
 *   value: number;
 * }
 *
 * interface State {
 *   items: Item[];
 *   filter: {
 *     value: string;
 *   }
 * }
 *
 * const getFilteredItems = createSelector<State>()(
 *   ['items', 'filter.value'],
 *   (items, filterValue) => items.filter((item) => item.includes(filterValue)),
 * );
 *
 * const state = {
 *   items: ['foo', 'bar', 'foo-bar'],
 *   filter: {
 *     value: 'foo'
 *   }
 * };
 *
 * console.log(getFilteredItems(state)); // ['foo', 'foo-bar'];
 * console.log(getFilteredItems(state)); // ['foo', 'foo-bar'], pulled from cache;
 */
export declare function createSelector<Args>(options?: CreateSelectorOptions): {
  <const Paths extends [Path<Args extends unknown[] ? Args : [Args]>]>(
    paths: Paths,
    getComputedValue?: undefined,
  ): IdentitySelector<Args extends unknown[] ? Args : [Args], Paths>;
  <
    const Paths extends Array<Path<Args extends unknown[] ? Args : [Args]>>,
    GetComputedValue extends ComputeValue<Args extends unknown[] ? Args : [Args], Paths, any>,
  >(
    paths: Paths,
    getComputedValue: GetComputedValue,
  ): StandardSelector<Args extends unknown[] ? Args : [Args], ReturnType<GetComputedValue>>;
  <const Paths extends PathStructured<Args extends unknown[] ? Args : [Args]>>(
    paths: Paths,
  ): IdentityStructuredSelector<Args extends unknown[] ? Args : [Args], Paths>;
  <
    const Paths extends PathStructured<Args extends unknown[] ? Args : [Args]>,
    GetComputedValue extends ComputeStructuredValue<Args extends unknown[] ? Args : [Args], Paths, any>,
  >(
    paths: Paths,
    getComputedValue: GetComputedValue,
  ): StandardSelector<Args extends unknown[] ? Args : [Args], ReturnType<GetComputedValue>>;
};
