export default update;
declare function update<S extends State>(state: S): ModifierType<S, S, S>;
declare function update<S extends ArrState<V>, V>(state: S, idx: number): ModifierType<S, V, V>;
declare function update<S extends ObjState, K extends keyof S>(state: S, key: K): ModifierType<S, S[K], S[K]>;
declare function update<S extends State>(state: S, getUpdates: (select: UpdateSelector<S, S>) => Update<S, any>[]): S;
declare function update<S extends State>(state: S, generateUpdates: (select: UpdateSelector<S, S>) => Generator<Update<S, any>>): S;
declare type ModifierType<S extends State, B extends Obj, T> = IfNeverThenNull<T extends (infer V)[] ? ArrayModifier<S, B, V> : never | T extends Record<string, any> ? ObjectModifier<S, B, T> : never>;
declare type ModifySelector<S extends State, B extends Obj> = {
    <K1 extends keyof B>(k1: K1): ModifierType<S, B, B[K1]>;
    <K1 extends keyof B, K2 extends keyof B[K1]>(k1: K1, k2: K2): ModifierType<S, B, B[K1][K2]>;
    <K1 extends keyof B, K2 extends keyof B[K1], K3 extends keyof B[K1][K2]>(k1: K1, k2: K2, k3: K3): ModifierType<S, B, B[K1][K2][K3]>;
    <K1 extends keyof B, K2 extends keyof B[K1], K3 extends keyof B[K1][K2], K4 extends keyof B[K1][K2][K3]>(k1: K1, k2: K2, k3: K3, k4: K4): ModifierType<S, B, B[K1][K2][K3][K4]>;
    <K1 extends keyof B, K2 extends keyof B[K1], K3 extends keyof B[K1][K2], K4 extends keyof B[K1][K2][K3], K5 extends keyof B[K1][K2][K3][K4]>(k1: K1, k2: K2, k3: K3, k4: K4, k5: K5): ModifierType<S, B, B[K1][K2][K3][K4][K5]>;
};
declare type ObjectModifier<S extends State, B extends Obj, T extends Record<string, any>> = {
    path: ModifySelector<S, B>;
    set<K extends keyof T>(key: K, value: T[K]): S;
    map<K extends keyof T>(key: K, mapper: (value: T[K]) => T[K]): S;
};
declare type ArrayModifier<S extends State, B extends State, V> = {
    path: ModifySelector<S, B>;
    push(item: V): S;
    pop(): S;
    map(mapper: (item: V, idx: number) => V): S;
    mapFirst(pred: (item: V, idx: number) => boolean, mapper: (item: V, idx: number) => V): S;
    filter(pred: (item: V, idx: number) => boolean): S;
    remove(pred: (item: V, idx: number) => boolean): S;
    removeFirst(pred: (item: V, idx: number) => boolean): S;
    removeLast(pred: (item: V, idx: number) => boolean): S;
    clear(): S;
};
declare type UpdaterType<S extends State, B extends State, T> = IfNeverThenNull<T extends (infer V)[] ? ArrayUpdater<S, B, V> : never | T extends Record<string, any> ? ObjectUpdater<S, B, T> : never>;
declare type ObjectUpdater<S extends State, B extends Obj, T extends Record<string, any>> = {
    select: UpdateSelector<S, B>;
    set<K extends keyof T>(key: K, value: T[K]): Update<S, T>;
    map<K extends keyof T>(key: K, mapper: (value: T[K]) => T[K]): Update<S, T>;
};
declare type ArrayUpdater<S extends State, B extends State, V> = {
    select: UpdateSelector<S, B>;
    push(value: V): Update<S, V[]>;
    pop(value: V): Update<S, V[]>;
    map(mapper: (item: V, idx: number) => V): Update<S, V[]>;
    mapFirst(pred: (item: V, idx: number) => boolean, mapper: (item: V, idx: number) => V): Update<S, V[]>;
    filter(pred: (item: V) => boolean): Update<S, V[]>;
    remove(pred: (item: V, idx: number) => boolean): Update<S, V[]>;
    removeFirst(pred: (item: V, idx: number) => boolean): Update<S, V[]>;
    removeLast(pred: (item: V, idx: number) => boolean): Update<S, V[]>;
    clear(): Update<S, V[]>;
};
declare type UpdateSelector<S extends State, B extends Obj> = {
    <K1 extends keyof B>(k1: K1): UpdaterType<S, B, B[K1]>;
    <K1 extends keyof B, K2 extends keyof B[K1]>(k1: K1, k2: K2): UpdaterType<S, B, B[K1][K2]>;
    <K1 extends keyof B, K2 extends keyof B[K1], K3 extends keyof B[K1][K2]>(k1: K1, k2: K2, k3: K3): UpdaterType<S, B, B[K1][K2][K3]>;
    <K1 extends keyof B, K2 extends keyof B[K1], K3 extends keyof B[K1][K2], K4 extends keyof B[K1][K2][K3]>(k1: K1, k2: K2, k3: K3, k4: K4): UpdaterType<S, B, B[K1][K2][K3][K4]>;
    <K1 extends keyof B, K2 extends keyof B[K1], K3 extends keyof B[K1][K2], K4 extends keyof B[K1][K2][K3], K5 extends keyof B[K1][K2][K3][K4]>(k1: K1, k2: K2, k3: K3, k4: K4, k5: K5): UpdaterType<S, B, B[K1][K2][K3][K4][K5]>;
};
declare type Update<S extends State, T> = {
    path: string[];
    mapper: (value: T) => T;
};
declare type Obj = Record<string, any>;
declare type ObjState = Record<string, any>;
declare type ArrState<V = any> = V[];
declare type State = ObjState | ArrState;
declare type IfNeverThenNull<T> = T extends never ? null : T;
