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