UNPKG

25.2 kBPlain TextView Raw
1/*
2 * Type definitions for Rematch v2.0.0
3 * Project: Rematch
4 * Definitions by:
5 * Shawn McKay https://github.com/shmck
6 * Bruno Lemos https://github.com/brunolemos
7 * Przemyslaw Jamrozowicz https://github.com/pjamrozowicz
8 * Tian Zhi https://github.com/tianzhich
9 */
10
11import {
12 Action as ReduxAction,
13 Reducer as ReduxReducer,
14 Dispatch as ReduxDispatch,
15 ReducersMapObject,
16 Middleware,
17 StoreEnhancer,
18 StoreCreator,
19 Store as ReduxStore,
20 ActionCreator,
21} from 'redux'
22
23/**
24 * Utility type used to check if the parameters in reducer/effects is optional
25 * Differentiate `[payload?: number]` from `[payload: number | undefined]`
26 * to improve ts experience
27 */
28type CheckIfParameterOptional<P> = P extends [unknown, ...unknown[]]
29 ? false
30 : true
31
32/**
33 * Utility type taken by type-fest repository
34 * https://github.com/sindresorhus/type-fest/blob/main/source/merge-exclusive.d.ts
35 * Merges Exclusively two types into one
36 * Used to fix this https://github.com/rematch/rematch/issues/912
37 */
38type Without<FirstType, SecondType> = {
39 [KeyType in Exclude<keyof FirstType, keyof SecondType>]: never
40}
41export type MergeExclusive<FirstType, SecondType> =
42 | FirstType
43 | SecondType extends object
44 ?
45 | (Without<FirstType, SecondType> & SecondType)
46 | (Without<SecondType, FirstType> & FirstType)
47 : FirstType | SecondType
48
49/**
50 * Custom Action interface, adds an additional field - `payload`.
51 *
52 * Strings (instead of Symbols) are used as the type for `type` field inherited
53 * from Redux, because strings are serializable.
54 *
55 * @template TPayload The type of the action's payload.
56 */
57export interface Action<TPayload = any, TMeta = any>
58 extends ReduxAction<string> {
59 payload?: TPayload
60 meta?: TMeta
61}
62
63/**
64 * Custom reducer which instead of an action (like in Redux), accepts payload as
65 * as a second argument.
66 *
67 * @template TState The type of state consumed and produced by this reducer.
68 */
69export type Reducer<TState = any> = (
70 state: TState,
71 payload?: Action['payload'],
72 meta?: Action['meta']
73) => TState | void
74
75/** ************************** Model *************************** */
76
77/**
78 * Mapping from a model key to model object.
79 *
80 * @template TModels List of all models
81 */
82export interface Models<TModels extends Models<TModels>> {
83 [key: string]: Model<TModels>
84}
85
86export interface NamedModel<
87 TModels extends Models<TModels>,
88 TState = any,
89 TBaseState = TState
90> extends Model<TModels, TState, TBaseState> {
91 name: string
92 reducers: ModelReducers<TState>
93}
94
95export interface Model<
96 TModels extends Models<TModels>,
97 TState = any,
98 TBaseState = TState
99> {
100 name?: string
101 state: TState
102 reducers?: ModelReducers<TState>
103 baseReducer?: ReduxReducer<TBaseState>
104 effects?: ModelEffects<TModels> | ModelEffectsCreator<TModels>
105}
106
107export type ModelReducers<TState = any> = {
108 [key: string]: Reducer<TState>
109}
110
111export interface ModelEffects<TModels extends Models<TModels>> {
112 [key: string]: ModelEffect<TModels>
113}
114
115export type ModelEffectThisTyped = {
116 [key: string]: (payload?: any, meta?: any) => Action<any, any>
117}
118
119export type ModelEffect<TModels extends Models<TModels>> = (
120 this: ModelEffectThisTyped,
121 payload: Action['payload'],
122 rootState: RematchRootState<TModels>,
123 meta: Action['meta']
124) => any
125
126export type ModelEffectsCreator<TModels extends Models<TModels>> = (
127 dispatch: RematchDispatch<TModels>
128) => ModelEffects<TModels>
129
130/** ************************** Plugin *************************** */
131
132export interface PluginConfig<
133 TModels extends Models<TModels>,
134 TExtraModels extends Models<TModels>,
135 TExposedModels = Partial<TExtraModels>
136> {
137 models?: TExposedModels
138 redux?: InitConfigRedux
139}
140
141export interface Plugin<
142 TModels extends Models<TModels>,
143 TExtraModels extends Models<TModels> = Record<string, never>,
144 TExposedModels = Partial<TExtraModels>
145> extends PluginHooks<TModels, TExtraModels> {
146 config?: PluginConfig<TModels, TExtraModels, TExposedModels>
147 exposed?: PluginExposed<TModels, TExtraModels>
148}
149
150export interface PluginHooks<
151 TModels extends Models<TModels>,
152 TExtraModels extends Models<TModels>
153> {
154 onStoreCreated?: StoreCreatedHook<TModels, TExtraModels>
155 onModel?: ModelHook<TModels, TExtraModels>
156 onReducer?: ReducerHook<TModels, TExtraModels>
157 onRootReducer?: RootReducerHook<TModels, TExtraModels>
158 createMiddleware?: MiddlewareCreator<TModels, TExtraModels>
159}
160
161export type ModelHook<
162 TModels extends Models<TModels>,
163 TExtraModels extends Models<TModels>
164> = (
165 model: NamedModel<TModels>,
166 rematch: RematchStore<TModels, TExtraModels>
167) => void
168
169export type ReducerHook<
170 TModels extends Models<TModels>,
171 TExtraModels extends Models<TModels>
172> = (
173 reducer: ReduxReducer,
174 modelName: string,
175 rematch: RematchBag<TModels, TExtraModels>
176) => ReduxReducer | void
177
178export type RootReducerHook<
179 TModels extends Models<TModels>,
180 TExtraModels extends Models<TModels>
181> = (
182 reducer: ReduxReducer,
183 rematch: RematchBag<TModels, TExtraModels>
184) => ReduxReducer | void
185
186export type StoreCreatedHook<
187 TModels extends Models<TModels>,
188 TExtraModels extends Models<TModels>
189> = (
190 store: RematchStore<TModels, TExtraModels>,
191 rematch: RematchBag<TModels, TExtraModels>
192) => RematchStore<TModels, TExtraModels> | void
193
194export type MiddlewareCreator<
195 TModels extends Models<TModels>,
196 TExtraModels extends Models<TModels> = Record<string, never>
197> = (rematch: RematchBag<TModels, TExtraModels>) => Middleware
198
199export type ObjectNotAFunction = { [k: string]: any } & (
200 | { bind?: never }
201 | { call?: never }
202)
203
204export type PluginExposed<
205 TModels extends Models<TModels>,
206 TExtraModels extends Models<TModels>
207> = {
208 [key: string]: ExposedFunction<TModels, TExtraModels> | ObjectNotAFunction
209}
210
211export type ExposedFunction<
212 TModels extends Models<TModels>,
213 TExtraModels extends Models<TModels>
214> = (rematch: RematchStore<TModels, TExtraModels>, ...args: any) => any
215
216/** ************************** Rematch *************************** */
217
218/**
219 * Object for storing information needed for the Rematch store to run.
220 * Purposefully hidden from the end user.
221 */
222export interface RematchBag<
223 TModels extends Models<TModels>,
224 TExtraModels extends Models<TModels>
225> {
226 models: NamedModel<TModels>[]
227 reduxConfig: ConfigRedux
228 forEachPlugin: <Hook extends keyof PluginHooks<TModels, TExtraModels>>(
229 method: Hook,
230 fn: (content: NonNullable<PluginHooks<TModels, TExtraModels>[Hook]>) => void
231 ) => void
232 effects: ModelEffects<TModels>
233}
234
235/**
236 * Initial, optional configuration provided by the user which describes how
237 * Rematch store should be configured.
238 */
239export interface InitConfig<
240 TModels extends Models<TModels>,
241 TExtraModels extends Models<TModels>
242> {
243 name?: string
244 models?: TModels | Partial<TModels>
245 plugins?: Plugin<TModels, TExtraModels>[]
246 redux?: InitConfigRedux
247}
248
249/**
250 * Config created out of the InitConfig by filling in missing properties with
251 * default values and merging in modifications required by plugins
252 * (new models, etc.).
253 */
254export interface Config<
255 TModels extends Models<TModels>,
256 TExtraModels extends Models<TModels>
257> extends InitConfig<TModels, TExtraModels> {
258 name: string
259 models: TModels | Partial<TModels>
260 plugins: Plugin<TModels, TExtraModels>[]
261 redux: ConfigRedux
262}
263
264/** ************************** Rematch-Redux *************************** */
265
266/**
267 * Initial, optional configuration for Redux, provided by the user. It allows
268 * to gain full control over the way Redux is configured by Rematch and
269 * override any defaults.
270 */
271export interface InitConfigRedux<
272 TRootState = any,
273 DevtoolComposerGeneric = any
274> {
275 initialState?: TRootState
276 reducers?: ModelReducers<TRootState>
277 enhancers?: StoreEnhancer[]
278 middlewares?: Middleware[]
279 rootReducers?: ReducersMapObject<TRootState, Action>
280 combineReducers?:
281 | ((
282 reducers: ReducersMapObject<TRootState, Action>
283 ) => ReduxReducer<TRootState>)
284 | undefined
285 createStore?: StoreCreator | undefined
286 devtoolOptions?: DevtoolOptions
287 devtoolComposer?: DevtoolComposerGeneric
288}
289
290/**
291 * Config created out of InitConfigRedux by supplying default values in place
292 * of missing properties.
293 */
294export interface ConfigRedux<TRootState = any>
295 extends InitConfigRedux<TRootState> {
296 reducers: ModelReducers<TRootState>
297 enhancers: StoreEnhancer[]
298 middlewares: Middleware[]
299 rootReducers: ReducersMapObject<TRootState, Action>
300}
301
302export interface RematchStore<
303 TModels extends Models<TModels>,
304 TExtraModels extends Models<TModels>
305> extends ReduxStore<RematchRootState<TModels, TExtraModels>, Action> {
306 [index: string]:
307 | ExposedFunction<TModels, TExtraModels>
308 | Record<string, any>
309 | string
310 name: string
311 dispatch: RematchDispatch<TModels>
312 addModel: (model: NamedModel<TModels>) => void
313}
314
315/** ************************** Root State *************************** */
316
317/**
318 * The type of state held by a store.
319 */
320export type RematchRootState<
321 TModels extends Models<TModels>,
322 TExtraModels extends Models<TModels> = Record<string, never>
323> = ExtractRematchStateFromModels<TModels, TExtraModels>
324
325/**
326 * A mapping from each model's name to a type of state it holds.
327 */
328export type ExtractRematchStateFromModels<
329 TModels extends Models<TModels>,
330 TExtraModels extends Models<TModels>
331> = {
332 [modelKey in keyof TModels]: TModels[modelKey]['state']
333} &
334 {
335 [modelKey in keyof TExtraModels]: TExtraModels[modelKey]['state']
336 }
337
338/** ************************** Dispatch *************************** */
339
340/**
341 * Rematch dispatch is a combination of regular redux dispatch method and
342 * an object allowing to dispatch specific actions by calling it the form of
343 * dispatch[modelName][reducerName | effectName](payload).
344 */
345export type RematchDispatch<TModels extends Models<TModels>> = ReduxDispatch &
346 ExtractRematchDispatchersFromModels<TModels>
347
348/**
349 * Goes over all models and extracts from each a type for dispatcher object
350 * created by Rematch.
351 */
352export type ExtractRematchDispatchersFromModels<
353 TModels extends Models<TModels>
354> = {
355 [modelKey in keyof TModels]: TModels[modelKey] extends Model<TModels>
356 ? ModelDispatcher<TModels[modelKey], TModels>
357 : never
358}
359
360/**
361 * Combines together types extracted from reducers and effects for a model.
362 */
363export type ModelDispatcher<
364 TModel extends Model<TModels>,
365 TModels extends Models<TModels>
366> = MergeExclusive<
367 ExtractRematchDispatchersFromEffects<TModel['effects'], TModels>,
368 ExtractRematchDispatchersFromReducers<
369 TModel['state'],
370 TModel['reducers'],
371 TModels
372 >
373>
374
375/**
376 * Get return type of rematch dispatcher
377 */
378export type ReturnOfDispatcher<
379 IsEffect extends boolean,
380 TReturn = any,
381 TPayload = void,
382 TMeta = void
383> = IsEffect extends true ? TReturn : Action<TPayload, TMeta>
384
385/**
386 * When payload is of type never, it describes 'empty' dispatcher - meaning
387 * it's a function not taking any arguments and returning an action.
388 * Otherwise, it describes dispatcher which accepts two optional argument (payload/meta)
389 * and returns an action.
390 */
391export type RematchDispatcher<
392 IsEffect extends boolean,
393 TPayload extends [p?: unknown] = never,
394 TMeta extends [m?: unknown] = never,
395 TReturn = any
396> = [TPayload, TMeta] extends [never, never]
397 ? (() => ReturnOfDispatcher<IsEffect, TReturn>) & { isEffect: IsEffect }
398 : [TMeta] extends [never]
399 ? CheckIfParameterOptional<TPayload> extends true
400 ? ((
401 payload?: TPayload[0]
402 ) => ReturnOfDispatcher<IsEffect, TReturn, TPayload[0]>) & {
403 isEffect: IsEffect
404 }
405 : ((
406 payload: TPayload[0]
407 ) => ReturnOfDispatcher<IsEffect, TReturn, TPayload[0]>) & {
408 isEffect: IsEffect
409 }
410 : CheckIfParameterOptional<TMeta> extends true
411 ? CheckIfParameterOptional<TPayload> extends true
412 ? ((
413 payload?: TPayload[0],
414 meta?: TMeta[0]
415 ) => ReturnOfDispatcher<IsEffect, TReturn, TPayload[0], TMeta[0]>) & {
416 isEffect: IsEffect
417 }
418 : ((
419 payload: TPayload[0],
420 meta?: TMeta[0]
421 ) => ReturnOfDispatcher<IsEffect, TReturn, TPayload[0], TMeta[0]>) & {
422 isEffect: IsEffect
423 }
424 : ((
425 payload: TPayload[0],
426 meta: TMeta[0]
427 ) => ReturnOfDispatcher<IsEffect, TReturn, TPayload[0], TMeta[0]>) & {
428 isEffect: IsEffect
429 }
430
431/** ************************ Reducers Dispatcher ************************* */
432
433/**
434 * Utility type used to extract the whole payload/meta parameter type
435 * from reducer parameters
436 * For example, extract `[meta?: string]`
437 * from `[payload: number, meta?: string]`
438 */
439type ExtractParameterFromReducer<
440 P extends unknown[],
441 V extends 'payload' | 'meta'
442> = P extends []
443 ? never
444 : P extends [p?: infer TPayload]
445 ? V extends 'payload'
446 ? P extends [infer TPayloadMayUndefined, ...unknown[]]
447 ? [p: TPayloadMayUndefined]
448 : [p?: TPayload]
449 : never
450 : P extends [p?: infer TPayload, m?: infer TMeta, ...args: unknown[]]
451 ? V extends 'payload'
452 ? P extends [infer TPayloadMayUndefined, ...unknown[]]
453 ? [p: TPayloadMayUndefined]
454 : [p?: TPayload]
455 : P extends [unknown, infer TMetaMayUndefined, ...unknown[]]
456 ? [m: TMetaMayUndefined]
457 : [m?: TMeta]
458 : never
459
460/**
461 * Extracts a dispatcher for each reducer that is defined for a model.
462 */
463export type ExtractRematchDispatchersFromReducers<
464 TState,
465 TReducers extends Model<TModels, TState>['reducers'],
466 TModels extends Models<TModels>
467> = {
468 [reducerKey in keyof TReducers]: ExtractRematchDispatcherFromReducer<
469 TState,
470 TReducers[reducerKey]
471 >
472}
473
474/**
475 * Matches a reducer to different forms and based on the form, selects an
476 * appropriate type for a dispatcher. Mapping goes like this:
477 * - reducer not taking any parameters -> 'empty' dispatcher
478 * - reducer only taking state -> 'empty' dispatcher
479 * - reducer taking state and optional payload (and may also taking optional meta)
480 * -> dispatcher accepting payload and meta as arguments
481 */
482export type ExtractRematchDispatcherFromReducer<TState, TReducer> =
483 TReducer extends () => any
484 ? RematchDispatcher<false>
485 : TReducer extends (state: TState, ...args: infer TRest) => TState | void
486 ? TRest extends []
487 ? RematchDispatcher<false>
488 : TRest[1] extends undefined
489 ? RematchDispatcher<false, ExtractParameterFromReducer<TRest, 'payload'>>
490 : RematchDispatcher<
491 false,
492 ExtractParameterFromReducer<TRest, 'payload'>,
493 ExtractParameterFromReducer<TRest, 'meta'>
494 >
495 : never
496
497/** ************************ Effects Dispatcher ************************* */
498
499/**
500 * Based on the shape of 'effects' property it extracts dispatchers from it.
501 * 'effects' can be:
502 * - empty - in this case the type is just never
503 * - an object defining effects
504 * - a function returning effects
505 * If it's a function it infers its return type which must define effects.
506 */
507export type ExtractRematchDispatchersFromEffects<
508 TEffects extends Model<TModels>['effects'],
509 TModels extends Models<TModels>
510> = TEffects extends (...args: any[]) => infer R
511 ? R extends ModelEffects<TModels>
512 ? ExtractRematchDispatchersFromEffectsObject<R, TModels>
513 : never
514 : TEffects extends ModelEffects<TModels>
515 ? ExtractRematchDispatchersFromEffectsObject<TEffects, TModels>
516 : never
517
518/**
519 * Extracts a dispatcher for each effect that is defined for a model.
520 */
521export type ExtractRematchDispatchersFromEffectsObject<
522 TEffects extends ModelEffects<TModels>,
523 TModels extends Models<TModels>
524> = {
525 [effectKey in keyof TEffects]: ExtractRematchDispatcherFromEffect<
526 TEffects[effectKey],
527 TModels
528 >
529}
530
531/**
532 * Utility type used to extract the whole payload/meta parameter type
533 * from effect parameters
534 * For example, extract `[meta?: string]`
535 * from `[payload: number, state: RootState, meta?: string]`
536 */
537type ExtractParameterFromEffect<
538 P extends unknown[],
539 V extends 'payload' | 'meta'
540> = P extends []
541 ? never
542 : P extends [p?: infer TPayload, s?: unknown]
543 ? V extends 'payload'
544 ? P extends [infer TPayloadMayUndefined, ...unknown[]]
545 ? [p: TPayloadMayUndefined]
546 : [p?: TPayload]
547 : never
548 : P extends [
549 p?: infer TPayload,
550 s?: unknown,
551 m?: infer TMeta,
552 ...args: unknown[]
553 ]
554 ? V extends 'payload'
555 ? P extends [infer TPayloadMayUndefined, ...unknown[]]
556 ? [p: TPayloadMayUndefined]
557 : [p?: TPayload]
558 : P extends [unknown, unknown, infer TMetaMayUndefined, ...unknown[]]
559 ? [m: TMetaMayUndefined]
560 : [m?: TMeta]
561 : never
562
563/**
564 * Matches an effect to different forms and based on the form, selects an
565 * appropriate type for a dispatcher. Mapping goes like this:
566 * - effect not taking any parameters -> 'empty' dispatcher
567 * - effect only taking payload -> dispatcher accepting payload as an argument
568 * - effect taking both payload and root state -> dispatcher accepting payload
569 * as an argument
570 * - effect taking payload, root state and meta -> dispatcher accepting payload
571 * and meta as arguments
572 */
573export type ExtractRematchDispatcherFromEffect<
574 TEffect extends ModelEffect<TModels>,
575 TModels extends Models<TModels>
576> = TEffect extends (...args: infer TRest) => infer TReturn
577 ? TRest extends []
578 ? RematchDispatcher<true, never, never, TReturn>
579 : TRest[1] extends undefined
580 ? RematchDispatcher<
581 true,
582 ExtractParameterFromEffect<TRest, 'payload'>,
583 never,
584 TReturn
585 >
586 : TRest[2] extends undefined
587 ? RematchDispatcher<
588 true,
589 ExtractParameterFromEffect<TRest, 'payload'>,
590 never,
591 TReturn
592 >
593 : RematchDispatcher<
594 true,
595 ExtractParameterFromEffect<TRest, 'payload'>,
596 ExtractParameterFromEffect<TRest, 'meta'>,
597 TReturn
598 >
599 : never
600
601export interface DevtoolOptions {
602 /**
603 * Disables Devtools options, useful for production usages
604 */
605 disabled?: boolean
606 /**
607 * the instance name to be showed on the monitor page. Default value is `document.title`.
608 * If not specified and there's no document title, it will consist of `tabId` and `instanceId`.
609 */
610 name?: string
611 /**
612 * action creators functions to be available in the Dispatcher.
613 */
614 actionCreators?: ActionCreator<any>[] | { [key: string]: ActionCreator<any> }
615 /**
616 * if more than one action is dispatched in the indicated interval, all new actions will be collected and sent at once.
617 * It is the joint between performance and speed. When set to `0`, all actions will be sent instantly.
618 * Set it to a higher value when experiencing perf issues (also `maxAge` to a lower value).
619 *
620 * @default 500 ms.
621 */
622 latency?: number
623 /**
624 * (> 1) - maximum allowed actions to be stored in the history tree. The oldest actions are removed once maxAge is reached. It's critical for performance.
625 *
626 * @default 50
627 */
628 maxAge?: number
629 /**
630 * - `undefined` - will use regular `JSON.stringify` to send data (it's the fast mode).
631 * - `false` - will handle also circular references.
632 * - `true` - will handle also date, regex, undefined, error objects, symbols, maps, sets and functions.
633 * - object, which contains `date`, `regex`, `undefined`, `error`, `symbol`, `map`, `set` and `function` keys.
634 * For each of them you can indicate if to include (by setting as `true`).
635 * For `function` key you can also specify a custom function which handles serialization.
636 * See [`jsan`](https://github.com/kolodny/jsan) for more details.
637 */
638 serialize?:
639 | boolean
640 | {
641 date?: boolean
642 regex?: boolean
643 undefined?: boolean
644 error?: boolean
645 symbol?: boolean
646 map?: boolean
647 set?: boolean
648 function?: boolean | Function
649 }
650 /**
651 * function which takes `action` object and id number as arguments, and should return `action` object back.
652 */
653 actionSanitizer?: <A extends Action>(action: A, id: number) => A
654 /**
655 * function which takes `state` object and index as arguments, and should return `state` object back.
656 */
657 stateSanitizer?: <S>(state: S, index: number) => S
658 /**
659 * *string or array of strings as regex* - actions types to be hidden / shown in the monitors (while passed to the reducers).
660 * If `actionsWhitelist` specified, `actionsBlacklist` is ignored.
661 */
662 actionsBlacklist?: string | string[]
663 /**
664 * *string or array of strings as regex* - actions types to be hidden / shown in the monitors (while passed to the reducers).
665 * If `actionsWhitelist` specified, `actionsBlacklist` is ignored.
666 */
667 actionsWhitelist?: string | string[]
668 /**
669 * called for every action before sending, takes `state` and `action` object, and returns `true` in case it allows sending the current data to the monitor.
670 * Use it as a more advanced version of `actionsBlacklist`/`actionsWhitelist` parameters.
671 */
672 predicate?: <S, A extends Action>(state: S, action: A) => boolean
673 /**
674 * if specified as `false`, it will not record the changes till clicking on `Start recording` button.
675 * Available only for Redux enhancer, for others use `autoPause`.
676 *
677 * @default true
678 */
679 shouldRecordChanges?: boolean
680 /**
681 * if specified, whenever clicking on `Pause recording` button and there are actions in the history log, will add this action type.
682 * If not specified, will commit when paused. Available only for Redux enhancer.
683 *
684 * @default "@@PAUSED""
685 */
686 pauseActionType?: string
687 /**
688 * auto pauses when the extensions window is not opened, and so has zero impact on your app when not in use.
689 * Not available for Redux enhancer (as it already does it but storing the data to be sent).
690 *
691 * @default false
692 */
693 autoPause?: boolean
694 /**
695 * if specified as `true`, it will not allow any non-monitor actions to be dispatched till clicking on `Unlock changes` button.
696 * Available only for Redux enhancer.
697 *
698 * @default false
699 */
700 shouldStartLocked?: boolean
701 /**
702 * if set to `false`, will not recompute the states on hot reloading (or on replacing the reducers). Available only for Redux enhancer.
703 *
704 * @default true
705 */
706 shouldHotReload?: boolean
707 /**
708 * if specified as `true`, whenever there's an exception in reducers, the monitors will show the error message, and next actions will not be dispatched.
709 *
710 * @default false
711 */
712 shouldCatchErrors?: boolean
713 /**
714 * If you want to restrict the extension, specify the features you allow.
715 * If not specified, all of the features are enabled. When set as an object, only those included as `true` will be allowed.
716 * Note that except `true`/`false`, `import` and `export` can be set as `custom` (which is by default for Redux enhancer), meaning that the importing/exporting occurs on the client side.
717 * Otherwise, you'll get/set the data right from the monitor part.
718 */
719 features?: {
720 /**
721 * start/pause recording of dispatched actions
722 */
723 pause?: boolean
724 /**
725 * lock/unlock dispatching actions and side effects
726 */
727 lock?: boolean
728 /**
729 * persist states on page reloading
730 */
731 persist?: boolean
732 /**
733 * export history of actions in a file
734 */
735 export?: boolean | 'custom'
736 /**
737 * import history of actions from a file
738 */
739 import?: boolean | 'custom'
740 /**
741 * jump back and forth (time travelling)
742 */
743 jump?: boolean
744 /**
745 * skip (cancel) actions
746 */
747 skip?: boolean
748 /**
749 * drag and drop actions in the history list
750 */
751 reorder?: boolean
752 /**
753 * dispatch custom actions or action creators
754 */
755 dispatch?: boolean
756 /**
757 * generate tests for the selected actions
758 */
759 test?: boolean
760 }
761 /**
762 * Set to true or a stacktrace-returning function to record call stack traces for dispatched actions.
763 * Defaults to false.
764 */
765 trace?: boolean | (<A extends Action>(action: A) => string)
766 /**
767 * The maximum number of stack trace entries to record per action. Defaults to 10.
768 */
769 traceLimit?: number
770 [key: string]: any
771}
772
773export interface ModelCreator {
774 <RM extends Models<RM>>(): <
775 R extends ModelReducers<S> | undefined,
776 BR extends ReduxReducer<BS> | undefined,
777 E extends ModelEffects<RM> | ModelEffectsCreator<RM> | undefined,
778 S,
779 BS = S
780 >(mo: {
781 name?: string
782 state: S
783 reducers?: R
784 baseReducer?: BR
785 effects?: E
786 }) => {
787 name?: string
788 state: S
789 } & (E extends undefined ? {} : { effects: E }) &
790 (R extends undefined ? {} : { reducers: R }) &
791 (BR extends undefined ? {} : { baseReducer: BR })
792}
793
794declare module 'redux' {
795 export interface Dispatch<A extends Action = AnyAction> {
796 [modelName: string]: any
797 }
798}
799
800/**
801 * Patch for the incompatibility between Redux.Dispatch and RematchDispatch
802 */
803declare module 'react-redux' {
804 interface Connect {
805 <RM extends Models<RM>, State, TStateProps, TDispatchProps, TOwnProps>(
806 mapStateToProps: MapStateToPropsParam<TStateProps, TOwnProps, State>,
807 mapDispatchToProps: MapRematchDispatchToPropsNonObject<
808 TDispatchProps,
809 TOwnProps,
810 RM
811 >
812 ): InferableComponentEnhancerWithProps<
813 TStateProps & TDispatchProps,
814 TOwnProps
815 >
816 }
817
818 type MapRematchDispatchToPropsNonObject<
819 TDispatchProps,
820 TOwnProps,
821 RM extends Models<RM>
822 > =
823 | MapRematchDispatchToPropsFactory<TDispatchProps, TOwnProps, RM>
824 | MapRematchDispatchToPropsFunction<TDispatchProps, TOwnProps, RM>
825
826 type MapRematchDispatchToPropsFactory<
827 TDispatchProps,
828 TOwnProps,
829 RM extends Models<RM>
830 > = (
831 dispatch: any,
832 ownProps: TOwnProps
833 ) => MapRematchDispatchToPropsFunction<TDispatchProps, TOwnProps, RM>
834
835 type MapRematchDispatchToPropsFunction<
836 TDispatchProps,
837 TOwnProps,
838 RM extends Models<RM>
839 > = (dispatch: any, ownProps: TOwnProps) => TDispatchProps
840}
841
842declare global {
843 interface Window {
844 __REDUX_DEVTOOLS_EXTENSION_COMPOSE__?: any
845 }
846}