Jan 26, 2020 First publish on Sep 21, 2019

Reduce redux-connect Typescript boilerplate

When you write React Redux connected component with Typescript, if you want a make sure your mapStatesToProps and mapDispatchToProps are typed-checked, often you need to write verbose code like below:

import * as React from 'react';
import { connect } from 'react-redux';
import { toggleTodo } from './actions';
import { selectTodoStatus, selectTodoDescription } from './selectors';
import { RootState } from './type';

interface ParentProps {
  id: string;
}

interface StoreProps {
  status: string;
  description: string;
}

interface DispatchProps {
  toggle: () => void;
}

const TodoItemView = (props: ParentProps & StoreProps & DispatchProps) => {
  return <div>...</div>;
};

const mapStatesToProps = (state: RootState, ownProps: ParentProps): StoreProps => ({
  status: selectTodoStatus(state, ownProps.id),
  description: selectTodoDescription(state, ownProps.id),
});

const mapDispatchToProps = (dispatch: any, ownProps: ParentProps): DispatchProps => ({
  toggle: () => dispatch(toggleTodo(ownProps.id)),
});

export const TodoItem = connect(mapStatesToProps, mapDispatchToProps)(TodoItemView);

And that’s a pain-in-the-ass, as your selectors and actions are already properly typed, now you need to duplicate it. In addition, everytime you want to inject a new props/new actions, you need to update both the typing and the mapProps function.

Recently, I’ve stumble upon ReturnType in Typescript, and that’s the solution to fix the boilerplate:

import * as React from 'react';
import { connect } from 'react-redux';
import type { Dispatch } from 'redux';

type TodoStatus = 'not_started' | 'in_progress' | 'done';

type 

Thanks for reading!

Love what you're reading? Sign up for my newsletter and stay up-to-date with my latest contents and projects.

    I won't send you spam or use it for other purposes.

    Unsubscribe at any time.