How To Get Props Types in Next.js and TypeScript

Avoid boilerplate code with InferGetServerSidePropsType and InferGetStaticPropsType and Automatically Infer the Types for Your Page Component Props

Next.js officially embraces TypeScript, offering several features to streamline your coding process and reduce boilerplate code. Among these features, InferGetServerSidePropsType and InferGetStaticPropsType stand out as particularly useful tools.

These features automatically deduce the types for your page component props when employing the getServerSideProps() or getStaticProps() functions, respectively. Despite their undeniable time-saving benefits, InferGetServerSidePropsType and InferGetStaticPropsType have some limitations that can result in a "props: never" error.

In the following sections, we'll explore how to make the most of InferGetServerSidePropsType and InferGetStaticPropsType while addressing their limitations.

Putting InferGetServerSidePropsType and InferGetStaticPropsType into Practice

Let's start by examining how InferGetServerSidePropsType works with an example:

import { InferGetServerSidePropsType } from "next"

type User = {
  name: string
  surname: string
  email: string
  age: number
  residence?: Residence
  //...
}

type Residence = {
  address: string
  zipCode: string
  country: {
    name: string
    isoCode?: string
  }
}

export default function UserPage({ user }: InferGetServerSidePropsType<typeof getServerSideProps>) {
  // The 'user' prop is automatically typed as 'User'
  const { name, surname, age } = user
  // ...
}

export function getServerSideProps() {
  const user: User = // Retrieve user data ...
  // Retrieve additional data ...

  return {
    props: {
      user: user,
      // Include other data...
    },
  }
}

As you can see, InferGetServerSidePropsType eliminates the need to explicitly declare the type of the user prop in the UserPage component as User. Without InferGetServerSidePropsType, the function signature for UserPage would look like this:

export default function UserPage({ user }: { user: User }) {
  // ...
}

This alternative approach involves repetitive code, boilerplate, and diminishes codebase maintainability.

It's essential to note that InferGetServerSidePropsType is tailored for use with getServerSideProps(), while InferGetStaticPropsType complements getStaticProps(). Their application and functionality are nearly identical. Therefore, a specific example showcasing InferGetStaticPropsType isn't necessary.

Resolving Type Inference Issues with infer-next-props-type

Type inference is a powerful tool, though it can encounter complexities that result in failures. As of Next.js version 12, both InferGetServerSidePropsType and InferGetStaticPropsType suffer from significant issues that lead to the inference of never as the props type, as documented here.

These limitations can pose challenges, especially when using the notFound feature. As per the official documentation, notFound is an optional boolean that triggers a redirection to the 404 page when set to true. Here's an example illustrating its usage:

export function getServerSideProps() {
  try {
    const user: User = // Retrieve user data ...
    // Retrieve other data ...

    return {
      props: {
        user: user,
        // Include other data...
      },
    }
  } catch (error) {
    return {
      notFound: true,
    }
  }
}

In this scenario, if the data retrieval logic encounters an error, the notFound boolean is set to true, resulting in a redirection to the 404 page.

Unfortunately, when this logic is applied, InferGetServerSidePropsType and InferGetStaticPropsType break and return never as the props type. In other words, these essential error handling mechanisms render InferGetServerSidePropsType and InferGetStaticPropsType unusable.

However, the GitHub user HaNdTriX has devised a solution with the infer-next-props-type TypeScript library. Employing it is straightforward. You merely need to import it as follows:

import InferNextPropsType from "infer-next-props-type";

Then, use it in your code like so:

import InferNextPropsType from "infer-next-props-type"

type User = {
  name: string
  surname: string
  email: string
  age: number
  residence?: Residence
  //...
}

type Residence = {
  address: string
  zipCode: string
  country: {
    name: string
    isoCode?: string
  }
}

export default function UserPage({ user }: InferNextPropsType<typeof getServerSideProps>) {
  // The 'user' prop is of type 'User'
  const { name, surname, age } = user
  // ...
}

export function getServerSideProps() {
  try {
    const user: User = // Retrieve user data ...
    // Retrieve other data ...

    return {
      props: {
        user: user,
        // Include other data...
      },
    }
  } catch (error) {
    return {
      notFound: true,
    }
  }
}

Simply replace InferGetServerSidePropsType or InferGetStaticPropsType with InferNextPropsType. This library works seamlessly with both getServerSideProps() and getStaticProps() and offers resolution for various scenarios that typically lead to standard Next.js inference failures. To explore the full list of cases addressed by this library, refer to this link.

Conclusion

In this article, you've acquired insights into using type inference effectively in Next.js and TypeScript. Next.js provides features like InferGetServerSidePropsType and InferGetStaticPropsType to minimize boilerplate code and enhance TypeScript development. However, these features come with limitations that can hinder their usability. Fortunately, the community has stepped in to resolve these issues, and this article has provided a comprehensive overview of these solutions.

Enjoyed this article?

Share it with your network to help others discover it

Continue Learning

Discover more articles on similar topics