1import { Action, AnyAction } from './actions' 2 3/* reducers */ 4 5/** 6 * A *reducer* (also called a *reducing function*) 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 */ 29export type Reducer<S = any, A extends Action = AnyAction> = ( 30 state: S | undefined, 31 action: A 32) => S 33 34/** 35 * Object whose values correspond to different reducer functions. 36 * 37 * @template A The type of actions the reducers can potentially respond to. 38 */ 39export type ReducersMapObject<S = any, A extends Action = AnyAction> = { 40 [K in keyof S]: Reducer<S[K], A> 41} 42 43/** 44 * Infer a combined state shape from a `ReducersMapObject`. 45 * 46 * @template M Object map of reducers as provided to `combineReducers(map: M)`. 47 */ 48export type StateFromReducersMapObject<M> = M extends ReducersMapObject 49 ? { [P in keyof M]: M[P] extends Reducer<infer S, any> ? S : never } 50 : never 51 52/** 53 * Infer reducer union type from a `ReducersMapObject`. 54 * 55 * @template M Object map of reducers as provided to `combineReducers(map: M)`. 56 */ 57export type ReducerFromReducersMapObject<M> = M extends { 58 [P in keyof M]: infer R 59} 60 ? R extends Reducer<any, any> 61 ? R 62 : never 63 : never 64 65/** 66 * Infer action type from a reducer function. 67 * 68 * @template R Type of reducer. 69 */ 70export type ActionFromReducer<R> = R extends Reducer<any, infer A> ? A : never 71 72/** 73 * Infer action union type from a `ReducersMapObject`. 74 * 75 * @template M Object map of reducers as provided to `combineReducers(map: M)`. 76 */ 77export type ActionFromReducersMapObject<M> = M extends ReducersMapObject 78 ? ActionFromReducer<ReducerFromReducersMapObject<M>> 79 : never 80