'How to make Next.js getStaticProps work with typescript
I am using Next.js with typescript feature enabled
Trying to use getStaticProps as described here https://nextjs.org/docs/basic-features/typescript
With GetStaticProps type
export const getStaticProps: GetStaticProps = () => {
return {
props: {
host: process.env.DB_HOST.toString(),
},
}
}
Type '() => { props: { host: string; }; }' is not assignable to type 'GetStaticProps<{ [key: string]: any; }, ParsedUrlQuery>'.
Type '{ props: { host: string; }; }' is missing the following properties from type 'Promise<GetStaticPropsResult<{ [key: string]: any; }>>': then, catch, [Symbol.toStringTag], finallyts(2322)
I am new to typescript so it's hard for me to figure out what it wants,
I would appreciate any help, thanks in advance
Here is the entire page code
import Head from 'next/head'
import styles from '../styles/Home.module.css'
import React from 'react'
import { GetStaticProps, GetStaticPropsContext } from 'next'
interface Props {
host: string
}
const Home: React.FC<Props> = (props) => {
return (
<div className={styles.container}>
<Head>
<title>Create Next App</title>
<link rel="icon" href="/favicon.ico" />
</Head>
<main className={styles.main}>
aa:{props.host}
<h1 className={styles.title}>
Welcome to <a href="https://nextjs.org">Next.js!</a>
</h1>
<p className={styles.description}>
Get started by editing <code className={styles.code}>pages/index.js</code>
</p>
<div className={styles.grid}>
<a href="https://nextjs.org/docs" className={styles.card}>
<h3>Documentation →</h3>
<p>Find in-depth information about Next.js features and API.</p>
</a>
<a href="https://nextjs.org/learn" className={styles.card}>
<h3>Learn →</h3>
<p>Learn about Next.js in an interactive course with quizzes!</p>
</a>
<a
href="https://github.com/vercel/next.js/tree/master/examples"
className={styles.card}
>
<h3>Examples →</h3>
<p>Discover and deploy boilerplate example Next.js projects.</p>
</a>
<a
href="https://vercel.com/import?filter=next.js&utm_source=create-next-app&utm_medium=default-template&utm_campaign=create-next-app"
className={styles.card}
>
<h3>Deploy →</h3>
<p>Instantly deploy your Next.js site to a public URL with Vercel.</p>
</a>
</div>
</main>
<footer className={styles.footer}>
<a
href="https://vercel.com?utm_source=create-next-app&utm_medium=default-template&utm_campaign=create-next-app"
target="_blank"
rel="noopener noreferrer"
>
Powered by <img src="/vercel.svg" alt="Vercel Logo" className={styles.logo} />
</a>
</footer>
</div>
)
}
export const getStaticProps: GetStaticProps = () => {
return {
props: {
host: process.env.DB_HOST.toString(),
},
}
}
export default Home
Solution 1:[1]
Your original example is almost correct but the getStaticProps function expression is missing async. Try this:
export const getStaticProps: GetStaticProps = async () => { // must be async
return {
props: {
host: process.env.DB_HOST.toString(),
},
};
};
This is not because of TS but the actual definition of getStaticProps() in Next.js.
Back to your example, even better would be to improve typing with the Props generic:
interface Props {
host: string;
}
export const getStaticProps: GetStaticProps<Props> = async () => {
return {
props: {
host: process.env.DB_HOST.toString(),
},
};
};
Solution 2:[2]
Answer is as follows:
export async function getStaticProps(context): Promise<GetStaticPropsResult<HomeProps>> {
return {
props: {
host: process.env.DB_HOST,
},
};
}
My colleague found the solution by checking GetStaticProps type definition:

Here is the whole page code
import Head from "next/head";
import styles from "../styles/Home.module.css";
import React from "react";
import { GetStaticPropsResult, GetStaticProps } from "next";
interface HomeProps {
host: string;
}
const Home: React.FC<HomeProps> = (props: HomeProps) => {
return (
<div className={styles.container}>
<Head>
<title>Create Next App</title>
<link rel="icon" href="/favicon.ico" />
</Head>
<main className={styles.main}>
aa:{props.host}
<h1 className={styles.title}>
Welcome to <a href="https://nextjs.org">Next.js!</a>
</h1>
<p className={styles.description}>
Get started by editing <code className={styles.code}>pages/index.js</code>
</p>
<div className={styles.grid}>
<a href="https://nextjs.org/docs" className={styles.card}>
<h3>Documentation →</h3>
<p>Find in-depth information about Next.js features and API.</p>
</a>
<a href="https://nextjs.org/learn" className={styles.card}>
<h3>Learn →</h3>
<p>Learn about Next.js in an interactive course with quizzes!</p>
</a>
<a href="https://github.com/vercel/next.js/tree/master/examples" className={styles.card}>
<h3>Examples →</h3>
<p>Discover and deploy boilerplate example Next.js projects.</p>
</a>
<a
href="https://vercel.com/import?filter=next.js&utm_source=create-next-app&utm_medium=default-template&utm_campaign=create-next-app"
className={styles.card}
>
<h3>Deploy →</h3>
<p>Instantly deploy your Next.js site to a public URL with Vercel.</p>
</a>
</div>
</main>
<footer className={styles.footer}>
<a
href="https://vercel.com?utm_source=create-next-app&utm_medium=default-template&utm_campaign=create-next-app"
target="_blank"
rel="noopener noreferrer"
>
Powered by <img src="/vercel.svg" alt="Vercel Logo" className={styles.logo} />
</a>
</footer>
</div>
);
};
export async function getStaticProps(context): Promise<GetStaticPropsResult<HomeProps>> {
return {
props: {
host: process.env.DB_HOST,
},
};
}
export default Home;
Solution 3:[3]
In short use this for constant reuse:
export const getStaticProps = async ({
params,
}: GetStaticPropsContext<PageParams>): Promise<
GetStaticPropsResult<ContentPageProps>
> => {
const { title, description } = await fetch(".../entity", { uuid: params.uuid })
return {
props: {
title,
description,
},
}
}
Here is what correct typing for getStaticProps looks like in page/content.tsx for me:
import type {
GetStaticPathsResult,
GetStaticPropsContext,
GetStaticPropsResult,
} from 'next'
type PageParams = {
uuid: string
}
type ContentPageProps = {
title: string
description: string
}
export default const ContentPage = ({ title, description }: ServicePageProps): JSX.Element => {
return (
<>
<h1>{title}</h1>
<p>{description}</p>
</>
)
}
export const getStaticProps = async ({
params,
}: GetStaticPropsContext<PageParams>): Promise<
GetStaticPropsResult<ContentPageProps>
> => {
const { title, description } = await fetch(".../entity", { uuid: params.uuid })
return {
props: {
title,
description,
},
}
}
export const getStaticPaths = async ({}): Promise<
GetStaticPathsResult<PageParams>
> => {
return {
paths: { params: { uuid: "54b659a1-3f20-4440-90b5-9107bd62b5ca" }},
fallback: false,
}
}
Notice
async (context:GetStaticPropsContext<PageParams>):
Promise<GetStaticPropsResult<ContentPageProps>
Where PageParams is derived from ParsedUrlQuery and ContentPageProps is what you will put into your component to render, can by any complexity (but not recursive).
Solution 4:[4]
I had same trouble as OP. This tutorial worked perfectly for me: https://www.vitamindev.com/next-js/getstaticprops-getstaticpaths-typescript/. It addressed the issue where getStaticPaths requires a type of ParsedUrlQuery. Authors offers extending it, as a solution. Please make you name your properties exactly(!) else TS will complain.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | dmudro |
| Solution 2 | asmodianis |
| Solution 3 | Roman M. Koss |
| Solution 4 |

