|
1 | 1 | /// <reference types="symbol-observable" /> |
2 | | -import { Dispatch, PreloadedState } from '../..' |
3 | 2 | import { Action, AnyAction } from './actions' |
4 | 3 | import { Reducer } from './reducers' |
5 | 4 |
|
| 5 | +/** |
| 6 | + * Internal "virtual" symbol used to make the `CombinedState` type unique. |
| 7 | + */ |
| 8 | +declare const $CombinedState: unique symbol |
| 9 | + |
| 10 | +/** |
| 11 | + * State base type for reducers created with `combineReducers()`. |
| 12 | + * |
| 13 | + * This type allows the `createStore()` method to infer which levels of the |
| 14 | + * preloaded state can be partial. |
| 15 | + * |
| 16 | + * Because Typescript is really duck-typed, a type needs to have some |
| 17 | + * identifying property to differentiate it from other types with matching |
| 18 | + * prototypes for type checking purposes. That's why this type has the |
| 19 | + * `$CombinedState` symbol property. Without the property, this type would |
| 20 | + * match any object. The symbol doesn't really exist because it's an internal |
| 21 | + * (i.e. not exported), and internally we never check its value. Since it's a |
| 22 | + * symbol property, it's not expected to be unumerable, and the value is |
| 23 | + * typed as always undefined, so its never expected to have a meaningful |
| 24 | + * value anyway. It just makes this type distinquishable from plain `{}`. |
| 25 | + */ |
| 26 | +export type CombinedState<S> = { readonly [$CombinedState]?: undefined } & S |
| 27 | + |
| 28 | +/** |
| 29 | + * Recursively makes combined state objects partial. Only combined state _root |
| 30 | + * objects_ (i.e. the generated higher level object with keys mapping to |
| 31 | + * individual reducers) are partial. |
| 32 | + */ |
| 33 | +export type PreloadedState<S> = Required<S> extends { |
| 34 | + [$CombinedState]: undefined |
| 35 | +} |
| 36 | + ? S extends CombinedState<infer S1> |
| 37 | + ? { |
| 38 | + [K in keyof S1]?: S1[K] extends object ? PreloadedState<S1[K]> : S1[K] |
| 39 | + } |
| 40 | + : never |
| 41 | + : { |
| 42 | + [K in keyof S]: S[K] extends object ? PreloadedState<S[K]> : S[K] |
| 43 | + } |
| 44 | + |
| 45 | +/** |
| 46 | + * A *dispatching function* (or simply *dispatch function*) is a function that |
| 47 | + * accepts an action or an async action; it then may or may not dispatch one |
| 48 | + * or more actions to the store. |
| 49 | + * |
| 50 | + * We must distinguish between dispatching functions in general and the base |
| 51 | + * `dispatch` function provided by the store instance without any middleware. |
| 52 | + * |
| 53 | + * The base dispatch function *always* synchronously sends an action to the |
| 54 | + * store's reducer, along with the previous state returned by the store, to |
| 55 | + * calculate a new state. It expects actions to be plain objects ready to be |
| 56 | + * consumed by the reducer. |
| 57 | + * |
| 58 | + * Middleware wraps the base dispatch function. It allows the dispatch |
| 59 | + * function to handle async actions in addition to actions. Middleware may |
| 60 | + * transform, delay, ignore, or otherwise interpret actions or async actions |
| 61 | + * before passing them to the next middleware. |
| 62 | + * |
| 63 | + * @template A The type of things (actions or otherwise) which may be |
| 64 | + * dispatched. |
| 65 | + */ |
| 66 | +export interface Dispatch<A extends Action = AnyAction> { |
| 67 | + <T extends A>(action: T, ...extraArgs: any[]): T |
| 68 | +} |
| 69 | + |
6 | 70 | /** |
7 | 71 | * Function to remove listener added by `Store.subscribe()`. |
8 | 72 | */ |
|
0 commit comments