UNPKG

28.1 kBTypeScriptView Raw
1import {
2 ClassAttributes,
3 Component,
4 ComponentClass,
5 Context,
6 JSX,
7 JSXElementConstructor,
8 NamedExoticComponent,
9 ReactNode,
10} from "react";
11
12import { Action, AnyAction, Dispatch, Store } from "redux";
13
14import hoistNonReactStatics = require("hoist-non-react-statics");
15
16/**
17 * This interface can be augmented by users to add default types for the root state when
18 * using `react-redux`.
19 * Use module augmentation to append your own type definition in a your_custom_type.d.ts file.
20 * https://www.typescriptlang.org/docs/handbook/declaration-merging.html#module-augmentation
21 */
22// eslint-disable-next-line @typescript-eslint/no-empty-interface
23export interface DefaultRootState {}
24
25export type AnyIfEmpty<T extends object> = keyof T extends never ? any : T;
26export type RootStateOrAny = AnyIfEmpty<DefaultRootState>;
27
28// Omit taken from https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-8.html
29export type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>;
30
31export type DistributiveOmit<T, K extends keyof T> = T extends unknown ? Omit<T, K> : never;
32
33export interface DispatchProp<A extends Action = AnyAction> {
34 dispatch: Dispatch<A>;
35}
36
37export type AdvancedComponentDecorator<TProps, TOwnProps> = (
38 component: JSXElementConstructor<TProps>,
39) => NamedExoticComponent<TOwnProps>;
40
41/**
42 * A property P will be present if:
43 * - it is present in DecorationTargetProps
44 *
45 * Its value will be dependent on the following conditions
46 * - if property P is present in InjectedProps and its definition extends the definition
47 * in DecorationTargetProps, then its definition will be that of DecorationTargetProps[P]
48 * - if property P is not present in InjectedProps then its definition will be that of
49 * DecorationTargetProps[P]
50 * - if property P is present in InjectedProps but does not extend the
51 * DecorationTargetProps[P] definition, its definition will be that of InjectedProps[P]
52 */
53export type Matching<InjectedProps, DecorationTargetProps> = {
54 [P in keyof DecorationTargetProps]: P extends keyof InjectedProps
55 ? InjectedProps[P] extends DecorationTargetProps[P] ? DecorationTargetProps[P]
56 : InjectedProps[P]
57 : DecorationTargetProps[P];
58};
59
60/**
61 * a property P will be present if :
62 * - it is present in both DecorationTargetProps and InjectedProps
63 * - InjectedProps[P] can satisfy DecorationTargetProps[P]
64 * ie: decorated component can accept more types than decorator is injecting
65 *
66 * For decoration, inject props or ownProps are all optionally
67 * required by the decorated (right hand side) component.
68 * But any property required by the decorated component must be satisfied by the injected property.
69 */
70export type Shared<
71 InjectedProps,
72 DecorationTargetProps,
73> = {
74 [P in Extract<keyof InjectedProps, keyof DecorationTargetProps>]?: InjectedProps[P] extends DecorationTargetProps[P]
75 ? DecorationTargetProps[P]
76 : never;
77};
78
79// Infers prop type from component C
80export type GetProps<C> = C extends JSXElementConstructor<infer P>
81 ? C extends ComponentClass<P> ? ClassAttributes<InstanceType<C>> & P : P
82 : never;
83
84// Applies LibraryManagedAttributes (proper handling of defaultProps
85// and propTypes).
86export type GetLibraryManagedProps<C> = JSX.LibraryManagedAttributes<C, GetProps<C>>;
87
88// Defines WrappedComponent and derives non-react statics.
89export type ConnectedComponent<
90 C extends JSXElementConstructor<any>,
91 P,
92> = NamedExoticComponent<P> & hoistNonReactStatics.NonReactStatics<C> & {
93 WrappedComponent: C;
94};
95
96// Injects props and removes them from the prop requirements.
97// Will not pass through the injected props if they are passed in during
98// render. Also adds new prop requirements from TNeedsProps.
99// Uses distributive omit to preserve discriminated unions part of original prop type
100export type InferableComponentEnhancerWithProps<TInjectedProps, TNeedsProps> = <
101 C extends JSXElementConstructor<Matching<TInjectedProps, GetProps<C>>>,
102>(
103 component: C,
104) => ConnectedComponent<
105 C,
106 DistributiveOmit<GetLibraryManagedProps<C>, keyof Shared<TInjectedProps, GetLibraryManagedProps<C>>> & TNeedsProps
107>;
108
109// Injects props and removes them from the prop requirements.
110// Will not pass through the injected props if they are passed in during
111// render.
112export type InferableComponentEnhancer<TInjectedProps> = InferableComponentEnhancerWithProps<TInjectedProps, {}>;
113
114export type InferThunkActionCreatorType<TActionCreator extends (...args: any[]) => any> = TActionCreator extends
115 (...args: infer TParams) => (...args: any[]) => infer TReturn ? (...args: TParams) => TReturn
116 : TActionCreator;
117
118export type HandleThunkActionCreator<TActionCreator> = TActionCreator extends (...args: any[]) => any
119 ? InferThunkActionCreatorType<TActionCreator>
120 : TActionCreator;
121
122// redux-thunk middleware returns thunk's return value from dispatch call
123// https://github.com/reduxjs/redux-thunk#composition
124export type ResolveThunks<TDispatchProps> = TDispatchProps extends { [key: string]: any } ? {
125 [C in keyof TDispatchProps]: HandleThunkActionCreator<TDispatchProps[C]>;
126 }
127 : TDispatchProps;
128
129// the conditional type is to support TypeScript 3.0, which does not support mapping over tuples and arrays;
130// once the typings are updated to at least TypeScript 3.1, a simple mapped type can replace this mess
131export type ResolveArrayThunks<TDispatchProps extends readonly any[]> = TDispatchProps extends
132 [infer A1, infer A2, infer A3, infer A4, infer A5, infer A6, infer A7, infer A8, infer A9] ? [
133 HandleThunkActionCreator<A1>,
134 HandleThunkActionCreator<A2>,
135 HandleThunkActionCreator<A3>,
136 HandleThunkActionCreator<A4>,
137 HandleThunkActionCreator<A5>,
138 HandleThunkActionCreator<A6>,
139 HandleThunkActionCreator<A7>,
140 HandleThunkActionCreator<A8>,
141 HandleThunkActionCreator<A9>,
142 ]
143 : TDispatchProps extends [infer A1, infer A2, infer A3, infer A4, infer A5, infer A6, infer A7, infer A8] ? [
144 HandleThunkActionCreator<A1>,
145 HandleThunkActionCreator<A2>,
146 HandleThunkActionCreator<A3>,
147 HandleThunkActionCreator<A4>,
148 HandleThunkActionCreator<A5>,
149 HandleThunkActionCreator<A6>,
150 HandleThunkActionCreator<A7>,
151 HandleThunkActionCreator<A8>,
152 ]
153 : TDispatchProps extends [infer A1, infer A2, infer A3, infer A4, infer A5, infer A6, infer A7] ? [
154 HandleThunkActionCreator<A1>,
155 HandleThunkActionCreator<A2>,
156 HandleThunkActionCreator<A3>,
157 HandleThunkActionCreator<A4>,
158 HandleThunkActionCreator<A5>,
159 HandleThunkActionCreator<A6>,
160 HandleThunkActionCreator<A7>,
161 ]
162 : TDispatchProps extends [infer A1, infer A2, infer A3, infer A4, infer A5, infer A6] ? [
163 HandleThunkActionCreator<A1>,
164 HandleThunkActionCreator<A2>,
165 HandleThunkActionCreator<A3>,
166 HandleThunkActionCreator<A4>,
167 HandleThunkActionCreator<A5>,
168 HandleThunkActionCreator<A6>,
169 ]
170 : TDispatchProps extends [infer A1, infer A2, infer A3, infer A4, infer A5] ? [
171 HandleThunkActionCreator<A1>,
172 HandleThunkActionCreator<A2>,
173 HandleThunkActionCreator<A3>,
174 HandleThunkActionCreator<A4>,
175 HandleThunkActionCreator<A5>,
176 ]
177 : TDispatchProps extends [infer A1, infer A2, infer A3, infer A4] ? [
178 HandleThunkActionCreator<A1>,
179 HandleThunkActionCreator<A2>,
180 HandleThunkActionCreator<A3>,
181 HandleThunkActionCreator<A4>,
182 ]
183 : TDispatchProps extends [infer A1, infer A2, infer A3]
184 ? [HandleThunkActionCreator<A1>, HandleThunkActionCreator<A2>, HandleThunkActionCreator<A3>]
185 : TDispatchProps extends [infer A1, infer A2] ? [HandleThunkActionCreator<A1>, HandleThunkActionCreator<A2>]
186 : TDispatchProps extends [infer A1] ? [HandleThunkActionCreator<A1>]
187 : TDispatchProps extends Array<infer A> ? Array<HandleThunkActionCreator<A>>
188 : TDispatchProps extends ReadonlyArray<infer A> ? ReadonlyArray<HandleThunkActionCreator<A>>
189 : never;
190
191/**
192 * Connects a React component to a Redux store.
193 *
194 * - Without arguments, just wraps the component, without changing the behavior / props
195 *
196 * - If 2 params are passed (3rd param, mergeProps, is skipped), default behavior
197 * is to override ownProps (as stated in the docs), so what remains is everything that's
198 * not a state or dispatch prop
199 *
200 * - When 3rd param is passed, we don't know if ownProps propagate and whether they
201 * should be valid component props, because it depends on mergeProps implementation.
202 * As such, it is the user's responsibility to extend ownProps interface from state or
203 * dispatch props or both when applicable
204 *
205 * @param mapStateToProps
206 * @param mapDispatchToProps
207 * @param mergeProps
208 * @param options
209 */
210export interface Connect<DefaultState = DefaultRootState> {
211 /* eslint-disable @definitelytyped/no-unnecessary-generics */
212 (): InferableComponentEnhancer<DispatchProp>;
213
214 <TStateProps = {}, no_dispatch = {}, TOwnProps = {}, State = DefaultState>(
215 mapStateToProps: MapStateToPropsParam<TStateProps, TOwnProps, State>,
216 ): InferableComponentEnhancerWithProps<TStateProps & DispatchProp, TOwnProps>;
217
218 <no_state = {}, TDispatchProps = {}, TOwnProps = {}>(
219 mapStateToProps: null | undefined,
220 mapDispatchToProps: MapDispatchToPropsNonObject<TDispatchProps, TOwnProps>,
221 ): InferableComponentEnhancerWithProps<TDispatchProps, TOwnProps>;
222
223 <no_state = {}, TDispatchProps = {}, TOwnProps = {}>(
224 mapStateToProps: null | undefined,
225 mapDispatchToProps: MapDispatchToPropsParam<TDispatchProps, TOwnProps>,
226 ): InferableComponentEnhancerWithProps<
227 ResolveThunks<TDispatchProps>,
228 TOwnProps
229 >;
230
231 <TStateProps = {}, TDispatchProps = {}, TOwnProps = {}, State = DefaultState>(
232 mapStateToProps: MapStateToPropsParam<TStateProps, TOwnProps, State>,
233 mapDispatchToProps: MapDispatchToPropsNonObject<TDispatchProps, TOwnProps>,
234 ): InferableComponentEnhancerWithProps<TStateProps & TDispatchProps, TOwnProps>;
235
236 <TStateProps = {}, TDispatchProps = {}, TOwnProps = {}, State = DefaultState>(
237 mapStateToProps: MapStateToPropsParam<TStateProps, TOwnProps, State>,
238 mapDispatchToProps: MapDispatchToPropsParam<TDispatchProps, TOwnProps>,
239 ): InferableComponentEnhancerWithProps<
240 TStateProps & ResolveThunks<TDispatchProps>,
241 TOwnProps
242 >;
243
244 <no_state = {}, no_dispatch = {}, TOwnProps = {}, TMergedProps = {}>(
245 mapStateToProps: null | undefined,
246 mapDispatchToProps: null | undefined,
247 mergeProps: MergeProps<undefined, DispatchProp, TOwnProps, TMergedProps>,
248 ): InferableComponentEnhancerWithProps<TMergedProps, TOwnProps>;
249
250 <TStateProps = {}, no_dispatch = {}, TOwnProps = {}, TMergedProps = {}, State = DefaultState>(
251 mapStateToProps: MapStateToPropsParam<TStateProps, TOwnProps, State>,
252 mapDispatchToProps: null | undefined,
253 mergeProps: MergeProps<TStateProps, DispatchProp, TOwnProps, TMergedProps>,
254 ): InferableComponentEnhancerWithProps<TMergedProps, TOwnProps>;
255
256 <no_state = {}, TDispatchProps = {}, TOwnProps = {}, TMergedProps = {}>(
257 mapStateToProps: null | undefined,
258 mapDispatchToProps: MapDispatchToPropsParam<TDispatchProps, TOwnProps>,
259 mergeProps: MergeProps<undefined, TDispatchProps, TOwnProps, TMergedProps>,
260 ): InferableComponentEnhancerWithProps<TMergedProps, TOwnProps>;
261
262 <TStateProps = {}, no_dispatch = {}, TOwnProps = {}, State = DefaultState>(
263 mapStateToProps: MapStateToPropsParam<TStateProps, TOwnProps, State>,
264 mapDispatchToProps: null | undefined,
265 mergeProps: null | undefined,
266 options: Options<State, TStateProps, TOwnProps>,
267 ): InferableComponentEnhancerWithProps<DispatchProp & TStateProps, TOwnProps>;
268
269 <TStateProps = {}, TDispatchProps = {}, TOwnProps = {}>(
270 mapStateToProps: null | undefined,
271 mapDispatchToProps: MapDispatchToPropsNonObject<TDispatchProps, TOwnProps>,
272 mergeProps: null | undefined,
273 options: Options<{}, TStateProps, TOwnProps>,
274 ): InferableComponentEnhancerWithProps<TDispatchProps, TOwnProps>;
275
276 <TStateProps = {}, TDispatchProps = {}, TOwnProps = {}>(
277 mapStateToProps: null | undefined,
278 mapDispatchToProps: MapDispatchToPropsParam<TDispatchProps, TOwnProps>,
279 mergeProps: null | undefined,
280 options: Options<{}, TStateProps, TOwnProps>,
281 ): InferableComponentEnhancerWithProps<
282 ResolveThunks<TDispatchProps>,
283 TOwnProps
284 >;
285
286 <TStateProps = {}, TDispatchProps = {}, TOwnProps = {}, State = DefaultState>(
287 mapStateToProps: MapStateToPropsParam<TStateProps, TOwnProps, State>,
288 mapDispatchToProps: MapDispatchToPropsNonObject<TDispatchProps, TOwnProps>,
289 mergeProps: null | undefined,
290 options: Options<State, TStateProps, TOwnProps>,
291 ): InferableComponentEnhancerWithProps<TStateProps & TDispatchProps, TOwnProps>;
292
293 <TStateProps = {}, TDispatchProps = {}, TOwnProps = {}, State = DefaultState>(
294 mapStateToProps: MapStateToPropsParam<TStateProps, TOwnProps, State>,
295 mapDispatchToProps: MapDispatchToPropsParam<TDispatchProps, TOwnProps>,
296 mergeProps: null | undefined,
297 options: Options<State, TStateProps, TOwnProps>,
298 ): InferableComponentEnhancerWithProps<
299 TStateProps & ResolveThunks<TDispatchProps>,
300 TOwnProps
301 >;
302
303 <TStateProps = {}, TDispatchProps = {}, TOwnProps = {}, TMergedProps = {}, State = DefaultState>(
304 mapStateToProps: MapStateToPropsParam<TStateProps, TOwnProps, State>,
305 mapDispatchToProps: MapDispatchToPropsParam<TDispatchProps, TOwnProps>,
306 mergeProps: MergeProps<TStateProps, TDispatchProps, TOwnProps, TMergedProps>,
307 options?: Options<State, TStateProps, TOwnProps, TMergedProps>,
308 ): InferableComponentEnhancerWithProps<TMergedProps, TOwnProps>;
309 /* eslint-enable @definitelytyped/no-unnecessary-generics */
310}
311
312/**
313 * Infers the type of props that a connector will inject into a component.
314 */
315export type ConnectedProps<TConnector> = TConnector extends
316 InferableComponentEnhancerWithProps<infer TInjectedProps, any>
317 ? unknown extends TInjectedProps
318 ? TConnector extends InferableComponentEnhancer<infer TInjectedProps> ? TInjectedProps
319 : never
320 : TInjectedProps
321 : never;
322
323/**
324 * The connect function. See {@type Connect} for details.
325 */
326export const connect: Connect;
327
328export type MapStateToProps<TStateProps, TOwnProps, State = DefaultRootState> = (
329 state: State,
330 ownProps: TOwnProps,
331) => TStateProps;
332
333export type MapStateToPropsFactory<TStateProps, TOwnProps, State = DefaultRootState> = (
334 initialState: State,
335 ownProps: TOwnProps,
336) => MapStateToProps<TStateProps, TOwnProps, State>;
337
338export type MapStateToPropsParam<TStateProps, TOwnProps, State = DefaultRootState> =
339 | MapStateToPropsFactory<TStateProps, TOwnProps, State>
340 | MapStateToProps<TStateProps, TOwnProps, State>
341 | null
342 | undefined;
343
344export type MapDispatchToPropsFunction<TDispatchProps, TOwnProps> = (
345 dispatch: Dispatch<Action>,
346 ownProps: TOwnProps,
347) => TDispatchProps;
348
349export type MapDispatchToProps<TDispatchProps, TOwnProps> =
350 | MapDispatchToPropsFunction<TDispatchProps, TOwnProps>
351 | TDispatchProps;
352
353export type MapDispatchToPropsFactory<TDispatchProps, TOwnProps> = (
354 dispatch: Dispatch<Action>,
355 ownProps: TOwnProps,
356) => MapDispatchToPropsFunction<TDispatchProps, TOwnProps>;
357
358export type MapDispatchToPropsParam<TDispatchProps, TOwnProps> =
359 | MapDispatchToPropsFactory<TDispatchProps, TOwnProps>
360 | MapDispatchToProps<TDispatchProps, TOwnProps>;
361
362export type MapDispatchToPropsNonObject<TDispatchProps, TOwnProps> =
363 | MapDispatchToPropsFactory<TDispatchProps, TOwnProps>
364 | MapDispatchToPropsFunction<TDispatchProps, TOwnProps>;
365
366export type MergeProps<TStateProps, TDispatchProps, TOwnProps, TMergedProps> = (
367 stateProps: TStateProps,
368 dispatchProps: TDispatchProps,
369 ownProps: TOwnProps,
370) => TMergedProps;
371
372export interface Options<State = DefaultRootState, TStateProps = {}, TOwnProps = {}, TMergedProps = {}>
373 extends ConnectOptions
374{
375 /**
376 * If true, implements shouldComponentUpdate and shallowly compares the result of mergeProps,
377 * preventing unnecessary updates, assuming that the component is a “pure” component
378 * and does not rely on any input or state other than its props and the selected Redux store’s state.
379 * Defaults to true.
380 * @default true
381 */
382 pure?: boolean | undefined;
383
384 /**
385 * When pure, compares incoming store state to its previous value.
386 * @default strictEqual
387 */
388 areStatesEqual?: ((nextState: State, prevState: State) => boolean) | undefined;
389
390 /**
391 * When pure, compares incoming props to its previous value.
392 * @default shallowEqual
393 */
394 areOwnPropsEqual?: ((nextOwnProps: TOwnProps, prevOwnProps: TOwnProps) => boolean) | undefined;
395
396 /**
397 * When pure, compares the result of mapStateToProps to its previous value.
398 * @default shallowEqual
399 */
400 areStatePropsEqual?: ((nextStateProps: TStateProps, prevStateProps: TStateProps) => boolean) | undefined;
401
402 /**
403 * When pure, compares the result of mergeProps to its previous value.
404 * @default shallowEqual
405 */
406 areMergedPropsEqual?: ((nextMergedProps: TMergedProps, prevMergedProps: TMergedProps) => boolean) | undefined;
407
408 /**
409 * If true, use React's forwardRef to expose a ref of the wrapped component
410 *
411 * @default false
412 */
413 forwardRef?: boolean | undefined;
414}
415
416/**
417 * Connects a React component to a Redux store. It is the base for {@link connect} but is less opinionated about
418 * how to combine <code>state</code>, <code>props</code>, and <code>dispatch</code> into your final props. It makes no
419 * assumptions about defaults or memoization of results, leaving those responsibilities to the caller.It does not
420 * modify the component class passed to it; instead, it returns a new, connected component for you to use.
421 *
422 * @param selectorFactory The selector factory. See SelectorFactory type for details.
423 * @param connectOptions If specified, further customizes the behavior of the connector. Additionally, any extra
424 * options will be passed through to your <code>selectorFactory</code> in the <code>factoryOptions</code> argument.
425 */
426// eslint-disable-next-line @definitelytyped/no-unnecessary-generics
427export function connectAdvanced<S, TProps, TOwnProps, TFactoryOptions = {}>(
428 selectorFactory: SelectorFactory<S, TProps, TOwnProps, TFactoryOptions>,
429 connectOptions?: ConnectOptions & TFactoryOptions,
430): AdvancedComponentDecorator<TProps, TOwnProps>;
431
432/**
433 * Initializes a selector function (during each instance's constructor). That selector function is called any time the
434 * connector component needs to compute new props, as a result of a store state change or receiving new props. The
435 * result of <code>selector</code> is expected to be a plain object, which is passed as the props to the wrapped
436 * component. If a consecutive call to <code>selector</code> returns the same object (<code>===</code>) as its previous
437 * call, the component will not be re-rendered. It's the responsibility of <code>selector</code> to return that
438 * previous object when appropriate.
439 */
440export type SelectorFactory<S, TProps, TOwnProps, TFactoryOptions> = (
441 dispatch: Dispatch<Action>,
442 factoryOptions: TFactoryOptions,
443) => Selector<S, TProps, TOwnProps>;
444
445export type Selector<S, TProps, TOwnProps = null> = TOwnProps extends null | undefined ? (state: S) => TProps
446 : (state: S, ownProps: TOwnProps) => TProps;
447
448export interface ConnectOptions {
449 /**
450 * Computes the connector component's displayName property relative to that of the wrapped component. Usually
451 * overridden by wrapper functions.
452 *
453 * @default name => 'ConnectAdvanced('+name+')'
454 * @param componentName
455 */
456 getDisplayName?: ((componentName: string) => string) | undefined;
457 /**
458 * Shown in error messages. Usually overridden by wrapper functions.
459 *
460 * @default 'connectAdvanced'
461 */
462 methodName?: string | undefined;
463 /**
464 * If defined, a property named this value will be added to the props passed to the wrapped component. Its value
465 * will be the number of times the component has been rendered, which can be useful for tracking down unnecessary
466 * re-renders.
467 *
468 * @default undefined
469 */
470 renderCountProp?: string | undefined;
471 /**
472 * Controls whether the connector component subscribes to redux store state changes. If set to false, it will only
473 * re-render on <code>componentWillReceiveProps</code>.
474 *
475 * @default true
476 */
477 shouldHandleStateChanges?: boolean | undefined;
478 /**
479 * The key of props/context to get the store. You probably only need this if you are in the inadvisable position of
480 * having multiple stores.
481 *
482 * @default 'store'
483 */
484 storeKey?: string | undefined;
485 /**
486 * @deprecated Use forwardRef
487 *
488 * @default false
489 */
490 withRef?: boolean | undefined;
491 /**
492 * The react context to get the store from.
493 *
494 * @default ReactReduxContext
495 */
496 context?: Context<ReactReduxContextValue> | undefined;
497}
498
499export interface ReactReduxContextValue<SS = any, A extends Action = AnyAction> {
500 store: Store<SS, A>;
501 storeState: SS;
502}
503
504export interface ProviderProps<A extends Action = AnyAction> {
505 /**
506 * The single Redux store in your application.
507 */
508 store: Store<any, A>;
509 /**
510 * Optional context to be used internally in react-redux. Use React.createContext() to create a context to be used.
511 * If this is used, generate own connect HOC by using connectAdvanced, supplying the same context provided to the
512 * Provider. Initial value doesn't matter, as it is overwritten with the internal state of Provider.
513 */
514 context?: Context<ReactReduxContextValue> | undefined;
515 children?: ReactNode;
516}
517
518/**
519 * Makes the Redux store available to the connect() calls in the component hierarchy below.
520 */
521export class Provider<A extends Action = AnyAction> extends Component<ProviderProps<A>> {}
522
523/**
524 * Exposes the internal context used in react-redux. It is generally advised to use the connect HOC to connect to the
525 * redux store instead of this approach.
526 */
527export const ReactReduxContext: Context<ReactReduxContextValue>;
528
529/**
530 * Wraps ReactDOM or React Native's internal unstable_batchedUpdate function. You can use it to ensure that
531 * multiple actions dispatched outside of React only result in a single render update.
532 */
533export function batch(cb: () => void): void;
534
535/* eslint-disable @definitelytyped/no-unnecessary-generics */
536
537/**
538 * Compares two arbitrary values for shallow equality. Object values are compared based on their keys, i.e. they must
539 * have the same keys and for each key the value must be equal according to the `Object.is()` algorithm. Non-object
540 * values are also compared with the same algorithm as `Object.is()`.
541 */
542export function shallowEqual<T>(left: T, right: any): boolean;
543
544/**
545 * A hook to access the redux `dispatch` function.
546 *
547 * Note for `redux-thunk` users: the return type of the returned `dispatch` functions for thunks is incorrect.
548 * However, it is possible to get a correctly typed `dispatch` function by creating your own custom hook typed
549 * from the store's dispatch function like this: `const useThunkDispatch = () => useDispatch<typeof store.dispatch>();`
550 *
551 * @returns redux store's `dispatch` function
552 *
553 * @example
554 *
555 * import React from 'react'
556 * import { useDispatch } from 'react-redux'
557 *
558 * export const CounterComponent = ({ value }) => {
559 * const dispatch = useDispatch()
560 * return (
561 * <div>
562 * <span>{value}</span>
563 * <button onClick={() => dispatch({ type: 'increase-counter' })}>
564 * Increase counter
565 * </button>
566 * </div>
567 * )
568 * }
569 */
570// NOTE: the first overload below and note above can be removed if redux-thunk typings add an overload for
571// the Dispatch function (see also this PR: https://github.com/reduxjs/redux-thunk/pull/247)
572export function useDispatch<TDispatch = Dispatch<any>>(): TDispatch;
573export function useDispatch<A extends Action = AnyAction>(): Dispatch<A>;
574
575/**
576 * A hook to access the redux store's state. This hook takes a selector function
577 * as an argument. The selector is called with the store state.
578 *
579 * This hook takes an optional equality comparison function as the second parameter
580 * that allows you to customize the way the selected state is compared to determine
581 * whether the component needs to be re-rendered.
582 *
583 * If you do not want to have to specify the root state type for whenever you use
584 * this hook with an inline selector you can use the `TypedUseSelectorHook` interface
585 * to create a version of this hook that is properly typed for your root state.
586 *
587 * @param selector the selector function
588 * @param equalityFn the function that will be used to determine equality
589 *
590 * @returns the selected state
591 *
592 * @example
593 *
594 * import React from 'react'
595 * import { useSelector } from 'react-redux'
596 * import { RootState } from './store'
597 *
598 * export const CounterComponent = () => {
599 * const counter = useSelector((state: RootState) => state.counter)
600 * return <div>{counter}</div>
601 * }
602 */
603export function useSelector<TState = DefaultRootState, TSelected = unknown>(
604 selector: (state: TState) => TSelected,
605 equalityFn?: (left: TSelected, right: TSelected) => boolean,
606): TSelected;
607
608/**
609 * This interface allows you to easily create a hook that is properly typed for your
610 * store's root state.
611 *
612 * @example
613 *
614 * interface RootState {
615 * property: string;
616 * }
617 *
618 * const useTypedSelector: TypedUseSelectorHook<RootState> = useSelector;
619 */
620export interface TypedUseSelectorHook<TState> {
621 <TSelected>(
622 selector: (state: TState) => TSelected,
623 equalityFn?: (left: TSelected, right: TSelected) => boolean,
624 ): TSelected;
625}
626
627/**
628 * A hook to access the redux store.
629 *
630 * @returns the redux store
631 *
632 * @example
633 *
634 * import React from 'react'
635 * import { useStore } from 'react-redux'
636 *
637 * export const ExampleComponent = () => {
638 * const store = useStore()
639 * return <div>{store.getState()}</div>
640 * }
641 */
642export function useStore<S = RootStateOrAny, A extends Action = AnyAction>(): Store<S, A>;
643
644/**
645 * Hook factory, which creates a `useSelector` hook bound to a given context.
646 *
647 * @param Context passed to your `<Provider>`.
648 * @returns A `useSelector` hook bound to the specified context.
649 */
650export function createSelectorHook<S = RootStateOrAny, A extends Action = AnyAction>(
651 context?: Context<ReactReduxContextValue<S, A>>,
652): <Selected extends unknown>(
653 selector: (state: S) => Selected,
654 equalityFn?: (previous: Selected, next: Selected) => boolean,
655) => Selected;
656
657/**
658 * Hook factory, which creates a `useStore` hook bound to a given context.
659 *
660 * @param Context passed to your `<Provider>`.
661 * @returns A `useStore` hook bound to the specified context.
662 */
663export function createStoreHook<S = RootStateOrAny, A extends Action = AnyAction>(
664 context?: Context<ReactReduxContextValue<S, A>>,
665): () => Store<S, A>;
666
667/**
668 * Hook factory, which creates a `useDispatch` hook bound to a given context.
669 *
670 * @param Context passed to your `<Provider>`.
671 * @returns A `useDispatch` hook bound to the specified context.
672 */
673export function createDispatchHook<S = RootStateOrAny, A extends Action = AnyAction>(
674 context?: Context<ReactReduxContextValue<S, A>>,
675): () => Dispatch<A>;
676
677/* eslint-enable @definitelytyped/no-unnecessary-generics */
678
\No newline at end of file