import { Functions } from './Functions';
import { Types } from './Types';
export declare function GroupBy<T extends {}>(data: T[]): {
    toObject<KEY extends keyof T & PropertyKey, TVAL extends PropertyKey & T[KEY] = T[KEY] & PropertyKey>(field: KEY): Readonly<Record<TVAL, T[]>>;
    toMap<KEY extends keyof T, TVAL extends T[KEY] = T[KEY]>(field: KEY): ReadonlyMap<TVAL, T[]>;
};
export declare namespace GroupBy {
    export abstract class Accumulator<T, R> {
        abstract consume(data: T): this;
        abstract get result(): R;
        abstract clear(): void;
        consumeAll(datas: T[]): this;
    }
    export function toObject<T extends {}>(): {
        byExtractor<KEY extends PropertyKey>(extractor: Functions.MapFunction<T, KEY>): ObjectGroupByBuilder<T, KEY>;
        byField<KEY extends keyof T, TVAL extends PropertyKey & T[KEY] = T[KEY] & PropertyKey>(field: KEY): ObjectGroupByBuilder<T, TVAL>;
    };
    export function toMap<T extends {}>(): {
        byExtractor<KEY>(extractor: Functions.MapFunction<T, KEY>): MapGroupByBuilder<T, KEY>;
        byField<KEY extends keyof T, TVAL extends PropertyKey & T[KEY] = T[KEY] & PropertyKey>(field: KEY): MapGroupByBuilder<T, TVAL>;
    };
    export class ObjectGroupByBuilder<T extends {}, KEY extends PropertyKey> {
        private readonly keyExtractor;
        constructor(keyExtractor: Functions.MapFunction<T, KEY>);
        valueExtractor<VALUE>(extractor: Functions.MapFunction<T, VALUE>): ObjectGroupByBuilderWithValue<T, KEY, VALUE>;
        build<GROUP>(groupAccumulatorsFactory: Functions.Provider<Accumulator<T, GROUP>>): ObjectGroupByAccumulator<T, KEY, T, GROUP>;
        build(): ObjectGroupByAccumulator<T, KEY, T, T[]>;
    }
    export class MapGroupByBuilder<T extends {}, KEY> {
        private readonly keyExtractor;
        constructor(keyExtractor: Functions.MapFunction<T, KEY>);
        valueExtractor<VALUE>(extractor: Functions.MapFunction<T, VALUE>): MapGroupByBuilderWithValue<T, KEY, VALUE>;
        build<GROUP>(groupAccumulatorsFactory: Functions.Provider<Accumulator<T, GROUP>>): MapGroupByAccumulator<T, KEY, T, GROUP>;
        build(): MapGroupByAccumulator<T, KEY, T, T[]>;
    }
    class ObjectGroupByBuilderWithValue<T extends {}, KEY extends PropertyKey, VALUE> {
        private readonly keyExtractor;
        private readonly valueExtractor;
        constructor(keyExtractor: Functions.MapFunction<T, KEY>, valueExtractor: Functions.MapFunction<T, VALUE>);
        build<GROUP>(groupAccumulatorsFactory: Functions.Provider<Accumulator<VALUE, GROUP>>): ObjectGroupByAccumulator<T, KEY, VALUE, GROUP>;
        build(): ObjectGroupByAccumulator<T, KEY, VALUE, VALUE[]>;
    }
    class MapGroupByBuilderWithValue<T extends {}, KEY, VALUE> {
        private readonly keyExtractor;
        private readonly valueExtractor;
        constructor(keyExtractor: Functions.MapFunction<T, KEY>, valueExtractor: Functions.MapFunction<T, VALUE>);
        build<GROUP>(groupAccumulatorsFactory: Functions.Provider<Accumulator<VALUE, GROUP>>): MapGroupByAccumulator<T, KEY, VALUE, GROUP>;
        build(): MapGroupByAccumulator<T, KEY, VALUE, VALUE[]>;
    }
    abstract class GroupByAccumulator<T extends {}, KEY, VALUE, GROUP, RESULT_CONTAINER> extends Accumulator<T, RESULT_CONTAINER> {
        private readonly keyExtractor;
        private readonly valueExtractor;
        private readonly groupAccumulatorsFactory;
        private readonly groupAccumulators;
        constructor(keyExtractor: Functions.MapFunction<T, KEY>, valueExtractor: Functions.MapFunction<T, VALUE>, groupAccumulatorsFactory: Functions.Provider<Accumulator<VALUE, GROUP>>);
        consume(data: T): this;
        clear(): void;
        abstract set(key: KEY, group: GROUP | Types.DeepReadonly<GROUP>): void;
        abstract get result(): Readonly<RESULT_CONTAINER>;
    }
    export class ObjectGroupByAccumulator<T extends {}, KEY extends PropertyKey, VALUE, GROUP> extends GroupByAccumulator<T, KEY, VALUE, GROUP, Record<KEY, GROUP>> {
        #private;
        set(key: KEY, group: GROUP): void;
        get result(): Readonly<Record<KEY, GROUP>>;
        clear(): void;
    }
    export class MapGroupByAccumulator<T extends {}, KEY, VALUE, GROUP> extends GroupByAccumulator<T, KEY, VALUE, GROUP, ReadonlyMap<KEY, GROUP>> {
        #private;
        set(key: KEY, group: GROUP): void;
        get result(): ReadonlyMap<KEY, GROUP>;
        clear(): void;
    }
    export class ArrayAccumulator<T> extends Accumulator<T, Readonly<T[]>> {
        #private;
        consume(data: T): this;
        consumeAll(datas: T[]): this;
        get result(): Readonly<T[]>;
        clear(): void;
    }
    export {};
}
