Skip to content

Instantly share code, notes, and snippets.

@adamterlson
Created January 22, 2019 07:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save adamterlson/bd3a9a01821c70348c0abce8e92224a5 to your computer and use it in GitHub Desktop.
Save adamterlson/bd3a9a01821c70348c0abce8e92224a5 to your computer and use it in GitHub Desktop.
Custom flowbindings for React-Redux
/* @flow */
import * as React from 'react'
import type { ComponentType, ElementConfig } from 'react'
declare type Action = { type: string }
declare type Dispatch = (arg: Action | Array<Action>) => mixed
declare type MapStateToProps<S, OP, SP> = (state: S, ownProps: OP) => SP
declare type MapDispatchToProps<OP, DP> = (dispatch: Dispatch, ownProps: OP) => DP
declare type MergeProps<SP, DP, OP, MP> = (stateProps: SP, dispatchProps: DP, ownProps: OP) => MP
declare type Connector<OP, T> = (wc: ComponentType<{ ...$Exact<OP>, ...$Exact<T> }>) => ComponentType<OP>
// connect()
declare function connect<S, OP>(): Connector<OP, { dispatch: Dispatch }>
// connect(fn, fn)
// connect(fn, {})
declare function connect<S, OP, SP, DP>(
mapDispatchToProps: MapStateToProps<S, OP, SP>,
mapDispatchToProps: MapDispatchToProps<OP, DP> | DP,
): Connector<OP, { ...$Exact<SP>, ...$Exact<DP> }>
// connect(fn)
declare function connect<S, OP, SP>(mapStateToProps: MapStateToProps<S, OP, SP>): Connector<OP, SP>
// connect(null, fn)
// connect(null, {})
declare function connect<OP, DP>(mapStateToProps: null, mapDispatchToProps: MapDispatchToProps<OP, DP> | DP): Connector<OP, DP>
// connect(fn, fn, fn)
// connect(fn, {}, fn)
declare function connect<S, OP, SP, DP, MP>(
mapDispatchToProps: MapStateToProps<S, OP, SP>,
mapDispatchToProps: MapDispatchToProps<OP, DP> | DP,
mergeProps: MergeProps<SP, DP, OP, MP>,
): Connector<OP, MP>
// Test Code
type ConnectProps = { foo: string, bar: () => mixed }
type OwnProps = { baz: number }
const mapStateToProps = (state, ownProps) => ({
foo: 'baz:' + ownProps.baz,
})
const mapDispatchToProps = (dispatch: Dispatch, ownProps) => ({
bar: () => dispatch({ type: 'yay!', payload: ownProps.baz }),
})
const mapDispatchToPropsObj = { bar: () => ({ type: 'yay!' }) }
const mergeProps = () => ({ merged: true })
const connector1: Connector<OwnProps, ConnectProps> = connect(mapStateToProps, mapDispatchToProps)
const connector2: Connector<OwnProps, ConnectProps> = connect(mapStateToProps, mapDispatchToPropsObj)
const connector3: Connector<OwnProps, { foo: string }> = connect(mapStateToProps)
const connector4: Connector<OwnProps, { bar: Function }> = connect(null, mapDispatchToProps)
const connector5: Connector<OwnProps, { bar: Function }> = connect(null, mapDispatchToPropsObj)
const connector6: Connector<OwnProps, { dispatch: Dispatch }> = connect()
const connector7: Connector<OwnProps, { merged: boolean }> = connect(mapStateToProps, mapDispatchToProps, mergeProps)
// const connector8: Connector<OwnProps, { dispatch: Dispatch, foo: string }> = connect(mapStateToProps)
// const connector9: Connector<OwnProps, { children: React.Node }> = connect(mapStateToProps)
const MyComponentCP = (props: OwnProps & ConnectProps) => <div />
const MyComponentMDTP = (props: OwnProps & { bar: Function }) => <div />
const MyComponentMSTP = (props: OwnProps & { foo: string }) => <div />
const MyComponentDispatch = (props: OwnProps & { dispatch: Dispatch }) => <div />
const MyComponentMerge = (props: { merged: boolean }) => <div />
// const MyComponentStateDispatch = (props: OwnProps & { foo: string, dispatch: Dispatch }) => <div />
const MyConnectedComponent1 = connector1(MyComponentCP)
const MyConnectedComponent2 = connector2(MyComponentCP)
const MyConnectedComponent3 = connector3(MyComponentMSTP)
const MyConnectedComponent4 = connector4(MyComponentMDTP)
const MyConnectedComponent5 = connector5(MyComponentMDTP)
const MyConnectedComponent6 = connector6(MyComponentDispatch)
const MyConnectedComponent7 = connector7(MyComponentMerge)
// const MyConnectedComponent8 = connector8(MyComponentStateDispatch)
console.log(<MyConnectedComponent1 baz={10} />)
console.log(<MyConnectedComponent2 baz={10} />)
console.log(<MyConnectedComponent3 baz={10} />)
console.log(<MyConnectedComponent4 baz={10} />)
console.log(<MyConnectedComponent5 baz={10} />)
console.log(<MyConnectedComponent6 baz={10} />)
console.log(<MyConnectedComponent7 baz={10} />)
// console.log(<MyConnectedComponent8 baz={10} />)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment