react-routerでRouteコンポーネントを使って<Route path='foo' component={Bar}/>
のように書くと、Barコンポーネントにはmatch,location,historyの3つのpropsが渡されます。
これらのpropsをどう型定義するかという話です。
Routing
例えば以下のようなroutingがあるとします。
<BrowserRouter>
<Switch>
<Route path="/counter" component={Counter} />
</Switch>
</BrowserRouter>
Counterコンポーネントにはmatch, location, historyのpropsが渡されます。
RouteComponentProps
Routeのcomponentに指定したコンポーネントのpropsはreact-router-domのRouteComponentPropsをextendする形で使えばうまく型定義できます。
import { RouteComponentProps } from 'react-router-dom'
interface Props extends RouteComponentProps<{}> {
// 他の型定義
}
const Counter = (props: Props) => (
<div>
<Navi history={props.history} />
</div>
)
RouteComponentPropsの型定義:
import * as React from 'react';
import * as H from 'history';
export interface RouteComponentProps<Params extends { [K in keyof Params]?: string } = {}, C extends StaticContext = StaticContext, S = H.LocationState> {
history: H.History;
location: H.Location<S>;
match: match<Params> | null;
staticContext?: C;
}
paramsが必要なときはRouteComponentProps<{id: string}>
という感じで渡してあげれば良いです。
History
さらにCounterがNaviという子コンポーネントを持っており、historyだけ渡している場合にNaviではどう型を定義するかというと、RouteComponentProps型定義でも使われているhistoryを使えば良いです。
import * as H from 'history'
interface Props {
history: H.History
}
const Navi = (props: Props) => (<div><button onClick={props.history.push('/next')}/><div/>)
locationの場合は、H.LocationでOK。
以上です。