Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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(),
        },
    }
}

I am getting error like this enter image description here

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 &rarr;</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 &rarr;</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 &rarr;</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 &rarr;</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
like image 798
asmodianis Avatar asked Nov 30 '20 17:11

asmodianis


People also ask

Can we use getStaticProps without getStaticPaths?

For Development, getStaticPaths and getStaticProps will be called on every request. Show activity on this post. You cant. getStaticProps will fetch data at build time and you won't be able to use data that's only available during request time, such as query parameters or HTTP headers.

Is next JS compatible with TypeScript?

Next. js provides an integrated TypeScript experience, including zero-configuration set up and built-in types for Pages, APIs, and more.

How do I enable TypeScript in next?

Using TypeScript in a Next. js app, you can use Create Next App. To enable TypeScript in a Next. js app, add a tsconfig. json file to the root of the project.


2 Answers

Hi Ran in to your issue but none of the answers above helped me.

I had a quick read in the documentation: https://nextjs.org/docs/basic-features/data-fetching#getstaticprops-static-generation

and found out that you the correct type for your getStaticProps should be:

import { GetStaticProps } from 'next'

export const getStaticProps: GetStaticProps = async (context) => {
  // ...
}

Then in your component:

import { InferGetStaticPropsType } from 'next'

type Post = {
  author: string
  content: string
}

export const getStaticProps = async () => {
  const res = await fetch('https://.../posts')
  const posts: Post[] = await res.json()

  return {
    props: {
      posts,
    },
  }
}

function Blog({ posts }: InferGetStaticPropsType<typeof getStaticProps>) {
  // will resolve posts to type Post[]
}

export default Blog

This will autogenerate a type from GetStaticProps to your component it worked for me 100%

like image 127
Bon Andre Opina Avatar answered Sep 17 '22 19:09

Bon Andre Opina


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(),
    },
  };
};
like image 32
dmudro Avatar answered Sep 18 '22 19:09

dmudro