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.