UNPKG

3.48 kBPlain TextView Raw
1import { 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 */
30export 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 */
43export 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 */
62export 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 */
75export 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 */
86export 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 */
95export 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 */
104export 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