1 | import { Action, UnknownAction } from './actions'
|
2 |
|
3 | /* reducers */
|
4 |
|
5 | /**
|
6 | * A *reducer* is a function that accepts
|
7 | * an accumulation and a value and returns a new accumulation. They are used
|
8 | * to reduce a collection of values down to a single value
|
9 | *
|
10 | * Reducers are not unique to Redux—they are a fundamental concept in
|
11 | * functional programming. Even most non-functional languages, like
|
12 | * JavaScript, have a built-in API for reducing. In JavaScript, it's
|
13 | * `Array.prototype.reduce()`.
|
14 | *
|
15 | * In Redux, the accumulated value is the state object, and the values being
|
16 | * accumulated are actions. Reducers calculate a new state given the previous
|
17 | * state and an action. They must be *pure functions*—functions that return
|
18 | * the exact same output for given inputs. They should also be free of
|
19 | * side-effects. This is what enables exciting features like hot reloading and
|
20 | * time travel.
|
21 | *
|
22 | * Reducers are the most important concept in Redux.
|
23 | *
|
24 | * *Do not put API calls into reducers.*
|
25 | *
|
26 | * @template S The type of state consumed and produced by this reducer.
|
27 | * @template A The type of actions the reducer can potentially respond to.
|
28 | * @template PreloadedState The type of state consumed by this reducer the first time it's called.
|
29 | */
|
30 | export type Reducer<
|
31 | S = any,
|
32 | A extends Action = UnknownAction,
|
33 | PreloadedState = S
|
34 | > = (state: S | PreloadedState | undefined, action: A) => S
|
35 |
|
36 | /**
|
37 | * Object whose values correspond to different reducer functions.
|
38 | *
|
39 | * @template S The combined state of the reducers.
|
40 | * @template A The type of actions the reducers can potentially respond to.
|
41 | * @template PreloadedState The combined preloaded state of the reducers.
|
42 | */
|
43 | export type ReducersMapObject<
|
44 | S = any,
|
45 | A extends Action = UnknownAction,
|
46 | PreloadedState = S
|
47 | > = keyof PreloadedState extends keyof S
|
48 | ? {
|
49 | [K in keyof S]: Reducer<
|
50 | S[K],
|
51 | A,
|
52 | K extends keyof PreloadedState ? PreloadedState[K] : never
|
53 | >
|
54 | }
|
55 | : never
|
56 |
|
57 | /**
|
58 | * Infer a combined state shape from a `ReducersMapObject`.
|
59 | *
|
60 | * @template M Object map of reducers as provided to `combineReducers(map: M)`.
|
61 | */
|
62 | export type StateFromReducersMapObject<M> = M[keyof M] extends
|
63 | | Reducer<any, any, any>
|
64 | | undefined
|
65 | ? {
|
66 | [P in keyof M]: M[P] extends Reducer<infer S, any, any> ? S : never
|
67 | }
|
68 | : never
|
69 |
|
70 | /**
|
71 | * Infer reducer union type from a `ReducersMapObject`.
|
72 | *
|
73 | * @template M Object map of reducers as provided to `combineReducers(map: M)`.
|
74 | */
|
75 | export type ReducerFromReducersMapObject<M> = M[keyof M] extends
|
76 | | Reducer<any, any, any>
|
77 | | undefined
|
78 | ? M[keyof M]
|
79 | : never
|
80 |
|
81 | /**
|
82 | * Infer action type from a reducer function.
|
83 | *
|
84 | * @template R Type of reducer.
|
85 | */
|
86 | export type ActionFromReducer<R> = R extends Reducer<any, infer A, any>
|
87 | ? A
|
88 | : never
|
89 |
|
90 | /**
|
91 | * Infer action union type from a `ReducersMapObject`.
|
92 | *
|
93 | * @template M Object map of reducers as provided to `combineReducers(map: M)`.
|
94 | */
|
95 | export type ActionFromReducersMapObject<M> = ActionFromReducer<
|
96 | ReducerFromReducersMapObject<M>
|
97 | >
|
98 |
|
99 | /**
|
100 | * Infer a combined preloaded state shape from a `ReducersMapObject`.
|
101 | *
|
102 | * @template M Object map of reducers as provided to `combineReducers(map: M)`.
|
103 | */
|
104 | export type PreloadedStateShapeFromReducersMapObject<M> = M[keyof M] extends
|
105 | | Reducer<any, any, any>
|
106 | | undefined
|
107 | ? {
|
108 | [P in keyof M]: M[P] extends (
|
109 | inputState: infer InputState,
|
110 | action: UnknownAction
|
111 | ) => any
|
112 | ? InputState
|
113 | : never
|
114 | }
|
115 | : never
|