Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
ConnectedProps - the missing TypeScript helper for Redux
import { InferableComponentEnhancerWithProps } from 'react-redux';
export default type ConnectedProps<T> = T extends InferableComponentEnhancerWithProps<infer Props, infer _> ? Props : never;
// credit: https://github.com/Voronar
// use it like this
import React from 'react';
import { connect } from 'react-redux';
import ConnectedProps from './ConnectedProps';
import { State, anAction, someOtherAction } from './yourReduxStuff';
const mapStateToProps = (state: State) => ({
slice: state.slice,
otherValue: state.some.otherValue,
});
const mapDispatchToProps = { // I've used the object shorthand, but all flavours of mapDispatchToProps will work
anAction,
someOtherAction,
};
// define your connector *before* the component, so you can use ConnectedProps to extract the types
const connector = connect(mapStateToProps, mapDispatchToProps);
type PropsFromRedux = ConnectedProps<typeof connector>;
// PropsFromRedux now has your store prop types automagically inferred
function SomeComponent({ slice, otherValue, anAction, someOtherAction }: PropsFromRedux) {
return ....
}
export default connector(SomeComponent);
@christianchown

This comment has been minimized.

@mbohgard

This comment has been minimized.

Copy link

@mbohgard mbohgard commented Nov 21, 2019

Thank you for this!

@markerikson

This comment has been minimized.

Copy link

@markerikson markerikson commented Nov 23, 2019

FYI, the ConnectedProps<T> type was added to @types/react-redux in v7.1.2:

DefinitelyTyped/DefinitelyTyped#37300
DefinitelyTyped/DefinitelyTyped#31227

And we now have a React-Redux "Static Typing" docs page that officially recommends using this pattern:

https://react-redux.js.org/using-react-redux/static-typing

Thank you for writing this gist, btw. I came across it a few months ago while researching ways to handle types for connect, and without this example, never would have learned about it or been able to publicly document the pattern.

@mbohgard

This comment has been minimized.

Copy link

@mbohgard mbohgard commented Nov 25, 2019

@markerikson Yes, I actually noticed this myself when I relied on VSCode auto import and it imported it from react-redux instead of my utility types. Thank you.

The most interesting bit though is how did you suddenly find this old gist just days after I replied? 😮

@markerikson

This comment has been minimized.

Copy link

@markerikson markerikson commented Nov 25, 2019

I actually found it a couple months ago :) I just now replied because we now have that info in the docs.

@chadmott

This comment has been minimized.

Copy link

@chadmott chadmott commented Nov 23, 2020

amazing thank you for this... for anyone interested in react-router + redux + TypesScript -- this is how I did it to get types working

import { RouteComponentProps, withRouter } from 'react-router-dom';

const mapStateToProps = (state: State) => ({
  someState
});

const mapDispatchToProps = {
  someFunc 
};

const connector = connect(mapStateToProps, mapDispatchToProps);
type PropsFromRedux = ConnectedProps<typeof connector>;

const MyComponent = ({
  SomeStateAsProps
}: PropsFromRedux & RouteComponentProps) => { // added the "& RouteComponentProps
return (
'working
);
}

export default connector(withRouter(MyComponent)); // <- no more squiggles
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment