Skip to content

Commit

Permalink
react-redux connect revamp (#1731)
Browse files Browse the repository at this point in the history
* basic use cases for connect covered

* support dispatch

* understand passing object as action creators

* mapDispatchToProps can be null

* mergeProps

* get rid of extra dispatches

* enhance dispatchers as object tests

* mapDispatchToProps can be null

* accept ConnectOptions

* remove unused declarations

* cleanup and unify type prop naming

* set lower bound to 0.57.1

* fine tune tests

* Support default props
Support Stateless functional components

* set proper Flow versions

* enhance connect options

* fix libdef test issue

* test react-redux with exact props

* fix typo
  • Loading branch information
villesau authored and AndrewSouthpaw committed Mar 5, 2018
1 parent 6475dcc commit dcd1531
Show file tree
Hide file tree
Showing 6 changed files with 425 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import type { Dispatch, Store } from "redux";

declare module "react-redux" {
import type { ComponentType, ElementConfig } from 'react';

declare export class Provider<S, A> extends React$Component<{
store: Store<S, A>,
children?: any
}> {}

declare export function createProvider(
storeKey?: string,
subKey?: string
): Provider<*, *>;

/*
S = State
A = Action
OP = OwnProps
SP = StateProps
DP = DispatchProps
MP = Merge props
MDP = Map dispatch to props object
RSP = Returned state props
RDP = Returned dispatch props
RMP = Returned merge props
Com = React Component
*/

declare type MapStateToProps<SP: Object, RSP: Object> = (state: Object, props: SP) => RSP;

declare type MapDispatchToProps<A, OP: Object, RDP: Object> = (dispatch: Dispatch<A>, ownProps: OP) => RDP;

declare type MergeProps<SP: Object, DP: Object, MP: Object, RMP: Object> = (
stateProps: SP,
dispatchProps: DP,
ownProps: MP
) => RMP;

declare type ConnectOptions<S: Object, OP: Object, RSP: Object, RMP: Object> = {|
pure?: boolean,
withRef?: boolean,
areStatesEqual?: (next: S, prev: S) => boolean,
areOwnPropsEqual?: (next: OP, prev: OP) => boolean,
areStatePropsEqual?: (next: RSP, prev: RSP) => boolean,
areMergedPropsEqual?: (next: RMP, prev: RMP) => boolean,
storeKey?: string
|};

declare type OmitDispatch<Component> = $Diff<Component, {dispatch: Dispatch<*>}>;

declare export function connect<Com: ComponentType<*>, DP: Object, RSP: Object>(
mapStateToProps: MapStateToProps<DP, RSP>,
mapDispatchToProps?: null
): (component: Com) => ComponentType<$Diff<OmitDispatch<ElementConfig<Com>>, RSP> & DP>;

This comment has been minimized.

Copy link
@mkholodnyak

mkholodnyak Jun 28, 2018

Hi, why do you force using ComponentType instead of Component here?

@villesau

This comment has been minimized.

Copy link
@villesau

villesau Jun 29, 2018

Author Member

That's the desired type when you look at the docs: https://flow.org/en/docs/react/types/#toc-react-componenttype

This is the type you want to use for functions that receive or return React components such as higher-order components or other utilities.


declare export function connect<Com: ComponentType<*>>(
mapStateToProps?: null,
mapDispatchToProps?: null
): (component: Com) => ComponentType<OmitDispatch<ElementConfig<Com>>>;

declare export function connect<Com: ComponentType<*>, A, DP: Object, SP: Object, RSP: Object, RDP: Object>(
mapStateToProps: MapStateToProps<SP, RSP>,
mapDispatchToProps: MapDispatchToProps<A, DP, RDP>
): (component: Com) => ComponentType<$Diff<$Diff<ElementConfig<Com>, RSP>, RDP> & SP & DP>;

declare export function connect<Com: ComponentType<*>, A, OP: Object, DP: Object,PR: Object>(
mapStateToProps?: null,
mapDispatchToProps: MapDispatchToProps<A, OP, DP>
): (Com) => ComponentType<$Diff<ElementConfig<Com>, DP> & OP>;

declare export function connect<Com: ComponentType<*>, MDP: Object>(
mapStateToProps?: null,
mapDispatchToProps: MDP
): (component: Com) => ComponentType<$Diff<ElementConfig<Com>, MDP>>;

declare export function connect<Com: ComponentType<*>, SP: Object, RSP: Object, MDP: Object>(
mapStateToProps: MapStateToProps<SP, RSP>,
mapDispatchToPRops: MDP
): (component: Com) => ComponentType<$Diff<$Diff<ElementConfig<Com>, RSP>, MDP> & SP>;

declare export function connect<Com: ComponentType<*>, A, DP: Object, SP: Object, RSP: Object, RDP: Object, MP: Object, RMP: Object>(
mapStateToProps: MapStateToProps<SP, RSP>,
mapDispatchToProps: ?MapDispatchToProps<A, DP, RDP>,
mergeProps: MergeProps<RSP, RDP, MP, RMP>
): (component: Com) => ComponentType<$Diff<ElementConfig<Com>, RMP> & SP & DP & MP>;

declare export function connect<Com: ComponentType<*>, A, DP: Object, SP: Object, RSP: Object, RDP: Object, MP: Object, RMP: Object>(
mapStateToProps: ?MapStateToProps<SP, RSP>,
mapDispatchToProps: ?MapDispatchToProps<A, DP, RDP>,
mergeProps: ?MergeProps<RSP, RDP, MP, RMP>,
options: ConnectOptions<*, SP & DP & MP, RSP, RMP>
): (component: Com) => ComponentType<$Diff<ElementConfig<Com>, RMP> & SP & DP & MP>;
}
11 changes: 11 additions & 0 deletions definitions/npm/react-redux_v5.x.x/flow_v0.62.0-/test_Provider.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// @flow
import React from "react";
import { Provider, createProvider } from "react-redux";

// $ExpectError
<Provider />; // missing store

const CustomProvider: Provider<*, *> = createProvider("ikea");

// $ExpectError
<CustomProvider />; // missing store
Loading

0 comments on commit dcd1531

Please sign in to comment.