ben tedder : code things

Typed connect using redux in React with Typescript

Lately I've been in the process of converting a React app to Typescript. My first try was a failure, too many errors and things to fix to justify the time I was spending. So I put it down and waited a few weeks. I'm back at it, and this time it was a success!

But there seemed to be a lot of boilerplate, especially when using Redux's connect. So here's what I've landed on, after viewing several blogs and example apps. This seems to be the cleanest and requires no extra files:

First, make sure you have yarn add @types/react-redux. I know it sounds obvious, but it tripped me up for ages.

Here we go:

// for stateful components
interface State {
  editing: boolean;
}

interface Props extends StateProps, DispatchProps { passedProp: number; }

// Stateless functional component version const MyClientComponent: React.SFC<Props> = (props: Props): JSX.Element => ( ...render here )

// Stateful component class const MyClientComponent = React.Component<Props, State> { ...other methods here }

interface StateProps { name: string; age: number; }

const mapStateToProps = (state: IState): StateProps => ({ name: state.client.name, age: state.client.age, });

interface DispatchProps { changeClientName: typeof changeClientName; changeClientAge: typeof changeClientAge; }

const mapDispatchToProps = (dispatch: Dispatch<State>): DispatchProps => ({ ...bindActionCreators({ changeClientName, changeClientAge, }, dispatch), });

export default connect(mapStateToProps, mapDispatchToProps)(MyClientComponent);

I've seen other blog posts where you can create a typed connect function, which I attempted. But after implementing I still couldn't get type checking on my components. That also could have been because typings weren't installed. Regardless, this current implementation doesn't feel too bad. It's at least a good place to start, and now I'm clear where my component props are all coming from.

Before I was getting a lot of errors about IntrinsicElement, IntrinsicAttributes, IntrinsicClassAttributes, etc., and now they're all cleaned up!