React + TypeScript で react-router の URLパラメーターを取得する時に、このようなコードでprops.match
を参照するとTS2339: Property 'match' does not exist on type '{ children?: ReactNode; }'.
とエラーがでました。
import React, {FC} from "react";
const Page: FC<{}> = props => {
return (
<div>This is {props.match.params.id} Page.</div>
)
};
export default Page;
たしかにmatchプロパティは、propsが受け取るオブジェクトとして定義されていないよな。。
と思ったものの、それならどのような型を読み込めば良いのかが分からなかったので調べました。
調べたみた所、react-router-dom の型定義ファイルにあるRouteComponentProps
を読み込めば良いとの事。
import React, {FC} from "react";
import {RouteComponentProps} from 'react-router-dom'
type PageProps = {} & RouteComponentProps<{id: string}>;
const Page: FC<PageProps> = props => {
return (
<div>This is {props.match.params.id} Page.</div>
)
};
export default Page;
コンポーネントが受け取るpropsの型とRouteComponentProps
を型結合してまとめて、コンポーネントの型定義にします。
RouteComponentProps
のコードは、下のようになっており、ジェネリクスで受け取る型定義でmatchプロパティの中にあるプロパティを指定する事ができます。
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>;
staticContext?: C;
}
参考
React Router with TypeScriptでちゃんと型をつける
What TypeScript type should I use to reference the match object in my props?