js-immutables
Version:
A small library to handle immutable data.
66 lines (65 loc) • 4.59 kB
TypeScript
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;