-
-
Notifications
You must be signed in to change notification settings - Fork 15.1k
Expand file tree
/
Copy pathreduceReducers.ts
More file actions
59 lines (58 loc) · 1.82 KB
/
reduceReducers.ts
File metadata and controls
59 lines (58 loc) · 1.82 KB
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
import type { NoInfer } from './createStore'
import type { Action } from './types/actions'
import type { Reducer } from './types/reducers'
/**
* Composes multiple reducers into one.
*
* @param initialState The initial state, which can be a different preloaded state.
* @param reducer The first reducer. Can accept a different preloaded state.
* @param reducers The rest of the reducers.
* @returns A reducer function that invokes every reducer passed in order, and returns the result of the last reducer.
*/
export default function reduceReducers<
S,
A extends Action,
Actions extends Action[],
P
>(
initialState: NoInfer<P | S> | undefined,
reducer: Reducer<S, A, P>,
...reducers: {
[K in keyof Actions]: Reducer<S, Actions[K]>
}
): Reducer<S, A | Actions[number], P>
/**
* Composes multiple reducers into one.
*
* @param reducer The first reducer. Can accept a different preloaded state.
* @param reducers The rest of the reducers.
* @returns A reducer function that invokes every reducer passed in order, and returns the result of the last reducer.
*/
export default function reduceReducers<
S,
A extends Action,
Actions extends Action[],
P
>(
reducer: Reducer<S, A, P>,
...reducers: {
[K in keyof Actions]: Reducer<S, Actions[K]>
}
): Reducer<S, A | Actions[number], P>
export default function reduceReducers<S, A extends Action, P>(
...args: [P | S | undefined | Reducer<S, A, P>, ...Array<Reducer<S, A>>]
): Reducer<S, A, P> {
const initialState =
typeof args[0] === 'function'
? undefined
: (args.shift() as P | S | undefined)
const [firstReducer, ...restReducers] = args as [
Reducer<S, A, P>,
...Reducer<S, A>[]
]
return (state = initialState, action) =>
restReducers.reduce(
(state, reducer) => reducer(state, action),
firstReducer(state, action)
)
}