Kitsune Blog

Kitsune Blog

getStaticPropsの型指定について簡単にまとめてみました。

TypeScript対応でNex.jsの静的サイト生成の要件の仕事をする機会があり、getStaticPropsの型指定を簡単にまとめてみました。

今回はJSONPlaceholderを用いてfetchのコードを記載しました。

公式ドキュメントはこちらです。

https://nextjs.org/docs/api-reference/data-fetching/get-static-props

基本

type Todo = {
  userId: number
  id: number
  title: string
  completed: boolean
}

export const getStaticProps = async () => {
  const response = await fetch('https://jsonplaceholder.typicode.com/todos/')
  const data= await response.json()
  return {
    props: {
      items: data as Todo[],
    },
  }
}

type Props = InferGetStaticPropsType<typeof getStaticProps>

const Home: NextPage<Props> = ({ items }) => {

InferGetStaticPropsTypeという型を推論する書き方で、getStaticProps内の戻り値の型を取得しています。

getStaticProps内ではfetchしたデータがany型になってしまうので、型アサーションを用いてTodo[]の型を当てています。

export const getStaticProps: GetStaticProps = async() => {

公式ドキュメントでも分けて記載されていますが、関数の戻り値の型にGetStaticPropsを当てる書き方とは共存できないです。

詳細ページなどでURLの情報を使う場合

詳細ページなどでは下記のようにparamsを用いてURLの情報を使うことになるかと思いますが、その場合getStaticPropsの引数にGetStaticPropsContext型を当てます。

export const getStaticProps = async(context: GetStaticPropsContext) => { 
 const response =
  await fetch(`https://jsonplaceholder.typicode.com/todos/${context.params?.id}`)
 const data = await response.json()
  return   props: {    
    item: data as Todo,   
   }, 
  }
}

type Props = InferGetStaticPropsType<typeof getStaticProps>

const Home: NextPage<Props>=({item}) =>

ISRなどを使う場合

ISRなどを導入していて、データの存在しないページにアクセスがあった場合への対応として、Redirectの処理を挟む場合はInferGetStaticPropsTypeによる型推論が機能しないです。

この場合はページのコンポーネントのPropsに直接用意した型を当てるしかなさそうです。

export const getStaticProps = async(context: GetStaticPropsContext) => { 
 const response =
  await fetch(`https://jsonplaceholder.typicode.com/todos/${context.params?.id}`)
 const data = await response.json()
 if (!data || !data.length) {    
  return {   
   redirect: { 
    destination:'/',   
    permanent:false   },    
 }
 return  props: {    
   item: data  as Todo,   
  }, 
 }
}

const Home: NextPage<{item:Todo}>  =({item}) => {