😊
Next.js の InferGetStaticPropsType が便利
Next.jsのサンプルリポジトリを眺めていたらInferGetStaticPropsType
というものを見つけました。これを使うと、getStaticPropsでreturnされた値をもとに、Pageに渡されるPropsの型を類推してくれます。
↓ ドキュメントはこちら
これまではこんな感じで書いていた
これまではProps
の型宣言を自分で書いていました。
import { GetStaticProps } from 'next';
// 👇
type Props = { posts: Post[] };
export const getStaticProps: GetStaticProps<Props> = async () => {
const { posts } = await getPosts();
return {
props: {
posts,
},
revalidate: 1
};
};
const Page: NextPage<Props> = (props) => { ... }
export default Page;
InferGetStaticPropsTypeを使うと…
InferGetStaticPropsType<typeof getStaticProps>
のように書くことで、getStaticProps()
の返り値をもとにPageに渡される型を類推してくれます。
import { InferGetStaticPropsType } from 'next';
// 👇
type Props = InferGetStaticPropsType<typeof getStaticProps>;
export const getStaticProps = async () => {
const { posts } = await getPosts(); // => { posts: Post[] }
return {
props: {
posts,
},
revalidate: 1
};
};
const Page: NextPage<Props> = (props) => { ... }
export default Page;
いつの間にこんなものが使えるようになっていた……?と思い、調べてみるとドキュメントに記載されたのは2020年5月のようです。
getStaticProps() 自体には型アノテーションをつけないこと
Teratailで「InferGetStaticPropsType
を使ったらany型になってしまった」という投稿を見つけたので、勝手にここで回答しちゃいます。
公式ドキュメントを参考にInferGetStaticPropsTypeを使ってみたのですが、コンポーネント内のitemsにマウスホバーするとany型が表示されています。
この質問者の方は以下のようなコードを書いている模様。
うまく類推が効かない例
import { GetStaticProps, InferGetStaticPropsType } from 'next';
export const getStaticProps: GetStaticProps = async () => {
const items: User[] = sampleUserData;
return { props: { items } };
};
// ...省略...
うまく類推が効かない理由はexport const getStaticProps: GetStaticProps = ...
というようにgetStaticProps()
に対してGetStaticProps
のアノテーションをつけてしまっているからだと思われます。: GetStaticProps
を外せばちゃんと類推されるはず。
getStaticProps()
の引数がanyにならない?
そうすると代わりにGetStaticPropsContext
を引数にあててあげれば良いですね!
import { InferGetStaticPropsType, GetStaticPropsContext } from 'next';
type Props = InferGetStaticPropsType<typeof getStaticProps>;
export const getStaticProps = async (context: GetStaticPropsContext) => {
const { query } = context
};
Discussion
以下のように、
GetStaticProps
のGenericsにprops
の型を指定してやるとInferGetStaticPropsTypes
側でもany
にならない様子でした。ここの指定がない場合、
props
が{[key: string]: any}
になるのでInferGetStaticPropsTypes
がany
になるのだと思います。