ys memos

Blog

next.jsのNextPageが違う型のPropsを受ける時の修正点


nextjs

2021/11/21


以前再入門したこともあり,Next.js + typescript の組み合わせの開発が大分板についてきたが,まだまだ理解が浅い点が多く残る.

今回,TypeScript


Props に記載した Interface の情報と実際に受け取る Props の情報が異なっている.


以下のコードが,問題を発生させるコードとなる.

このコードを利用すると,title['hoge']という Props が与えられてしまう(!?).

JS/TS に慣れている方ならすぐに問題点が分かると思うが,少しこのコードの問題点を探してみてほしい.

interface PostProps {
  title: string;
  content: string;
}

const Post: NextPage<PostProps> = ({ title, content }) => {
  // 何故か title に `['hoge']` が入っている
  return (
    // 描画
  );
};

export const getStaticProps: GetStaticProps = async ({ params }) => {
  // ここでデータ取得の処理
  // filepathには`/posts/hoge`が入っているとする
  return {
    props: {
      title: filepath.split('/').slice(-1),
      content,
    },
  };
};

Array<string>.prototype.slice()の戻り値の型はstring[]である.

つまり,要素が 1 つであろうと,長さ1の配列としてprops.titleに渡していた.

解決するためには,filepath.split('/').slice(-1)[0]のようにする必要がある.


ライブラリの実装を見る元気はなかったが,発生した事象を鑑みると,VSCode による型チェックがうまく機能していなかったと思う. しかし,VSCode が悪いのではなく,型チェックする場所と Next.js 特有の形式がうまく噛み合わなかったのだと思う.

具体的に,普段の開発時に型エラーを教えてくれる場所は,関数・コンポーネントの利用場所である.

Next.js においてNextPageを実際に呼び出すのは開発者ではなく,ルーティングと共に Next.js 内部で行ってくれる.その時に同時にgetStaticPropsの戻り値も渡してくれる.

これらにより,開発時にはgetStaticProps/NextPageは繋がっているように感じる一方,開発者は明示的にNextPageを呼び出さないので VSCode としては「getStaticPropsの戻り値がNextPageに渡されるなんて知らないよ」となるのだろう.


処理面での解決策は上述の通り,0 番目の要素を渡すとよい.

開発時に型チェックをしてもらうためには,GetStaticPropsに忘れずにPostPropsを入れることにより,getStaticPropsの戻り値の型を縛る.

- export const getStaticProps: GetStaticProps = async ({ params }) => {
+ export const getStaticProps: GetStaticProps<PostProps> = async ({ params }) => {
    return {
      props: {
-       title: filepath.split('/').slice(-1),
+       title: filepath.split('/').slice(-1)[0],
        content,
      },
    };

TypeScript が便利なぶん,型のエラーが出力されない内部的な不整合に対する耐性が弱まったように感じる.

この一言で表すと欠点のように感じなくもないが,これは,開発中の思考の矛先を絞れているという事にもとれるのではないか.ということになり,結果的に TypeScript による開発効率の向上がしっかりと出来ているという実感が残った.


none

関連タグを探す