TypeScript で react-router + Redux を使う(mapStateToProps編)

react-router と Redux を組み合わせるときは、withRouter を使うことでコンポーネントhistorylocation (URLパスやクエリ) などを渡すことができる。 それを Redux の mapStateToProps でゴニョゴニョすることでURLパスやクエリとStoreのデータを組み合わせることができる。

その際、mapStateToProps = (state, props) => {...}props にどのような型をつければいいか調べたのでメモ

TL;DR

RouteComponentProps を使う。

使い方

通常のURLの場合、RouteComponentProps<{}> とする。

"/users/:userId" のような形で、URL内にユーザーIDなどのパラメータがある場合、RouteComponentProps<{userId: string}> のように、パラメータの型を引数に与える。

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

// URLにパラメータがない場合
const mapStateToProps = (_, props: RouteComponentProps<{}>) => {
    console.log(props)
    return {
      ...
    }
  }

// URLにパラメータがある場合
const mapStateToProps = (_, props: RouteComponentProps<{userId: string}>) => {
    console.log(props)
    return {
      ...
    }
  }

解説

react-router の index.d.ts を抜粋すると以下のようになっている。

import * as H from 'history';

export interface RouteComponentProps<P, C extends StaticContext = StaticContext> {
  history: H.History;
  location: H.Location;
  match: match<P>;
  staticContext: C | undefined;
}

export interface match<P> {
  params: P;
  isExact: boolean;
  path: string;
  url: string;
}

この RouteComponentProps が、 withRouter が渡す引数の型とドンピシャなのでこれを使う。 よくみると第一引数 Pmatch<> に渡しており、この P でURLパラメータの型を指定できる。