-
-
Notifications
You must be signed in to change notification settings - Fork 2k
/
Copy pathutils.ts
116 lines (102 loc) · 3.31 KB
/
utils.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
import {
Action,
ActionReducer,
ActionReducerMap,
ActionReducerFactory,
MetaReducer,
} from './models';
export function combineReducers<T, V extends Action = Action>(
reducers: ActionReducerMap<T, V>,
initialState?: Partial<T>
): ActionReducer<T, V>;
export function combineReducers(
reducers: any,
initialState: any = {}
): ActionReducer<any, Action> {
const reducerKeys = Object.keys(reducers);
const finalReducers: any = {};
for (let i = 0; i < reducerKeys.length; i++) {
const key = reducerKeys[i];
if (typeof reducers[key] === 'function') {
finalReducers[key] = reducers[key];
}
}
const finalReducerKeys = Object.keys(finalReducers);
return function combination(state, action) {
state = state === undefined ? initialState : state;
let hasChanged = false;
const nextState: any = {};
for (let i = 0; i < finalReducerKeys.length; i++) {
const key = finalReducerKeys[i];
const reducer: any = finalReducers[key];
const previousStateForKey = state[key];
const nextStateForKey = reducer(previousStateForKey, action);
nextState[key] = nextStateForKey;
hasChanged = hasChanged || nextStateForKey !== previousStateForKey;
}
return hasChanged ? nextState : state;
};
}
export function omit<T extends { [key: string]: any }>(
object: T,
keyToRemove: keyof T
): Partial<T> {
return Object.keys(object)
.filter(key => key !== keyToRemove)
.reduce((result, key) => Object.assign(result, { [key]: object[key] }), {});
}
export function compose<A>(): (i: A) => A;
export function compose<A, B>(b: (i: A) => B): (i: A) => B;
export function compose<A, B, C>(c: (i: B) => C, b: (i: A) => B): (i: A) => C;
export function compose<A, B, C, D>(
d: (i: C) => D,
c: (i: B) => C,
b: (i: A) => B
): (i: A) => D;
export function compose<A, B, C, D, E>(
e: (i: D) => E,
d: (i: C) => D,
c: (i: B) => C,
b: (i: A) => B
): (i: A) => E;
export function compose<A, B, C, D, E, F>(
f: (i: E) => F,
e: (i: D) => E,
d: (i: C) => D,
c: (i: B) => C,
b: (i: A) => B
): (i: A) => F;
export function compose(...functions: any[]) {
return function(arg: any) {
if (functions.length === 0) {
return arg;
}
const last = functions[functions.length - 1];
const rest = functions.slice(0, -1);
return rest.reduceRight((composed, fn) => fn(composed), last(arg));
};
}
export function createReducerFactory<T, V extends Action = Action>(
reducerFactory: ActionReducerFactory<T, V>,
metaReducers?: MetaReducer<T, V>[]
): ActionReducerFactory<T, V> {
if (Array.isArray(metaReducers) && metaReducers.length > 0) {
return compose.apply(null, [...metaReducers, reducerFactory]);
}
return reducerFactory;
}
export function createFeatureReducerFactory<T, V extends Action = Action>(
metaReducers?: MetaReducer<T, V>[]
): (reducer: ActionReducer<T, V>, initialState?: T) => ActionReducer<T, V> {
const reducerFactory =
Array.isArray(metaReducers) && metaReducers.length > 0
? compose<ActionReducer<T, V>>(...metaReducers)
: (r: ActionReducer<T, V>) => r;
return (reducer: ActionReducer<T, V>, initialState?: T) => {
reducer = reducerFactory(reducer);
return (state: T | undefined, action: V) => {
state = state === undefined ? initialState : state;
return reducer(state, action);
};
};
}