如何使 Next.js getStaticProps 与打字稿一起使用

Posted

技术标签:

【中文标题】如何使 Next.js getStaticProps 与打字稿一起使用【英文标题】:How to make Next.js getStaticProps work with typescript 【发布时间】:2021-03-12 15:37:37 【问题描述】:

我正在使用启用了 typescript 功能的 Next.js

尝试使用此处描述的 getStaticProps https://nextjs.org/docs/basic-features/typescript

使用 GetStaticProps 类型

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)

我是 typescript 的新手,所以我很难弄清楚它想要什么,

如果有任何帮助,我将不胜感激,在此先感谢

这是整个页面的代码

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"  className=styles.logo />
                </a>
            </footer>
        </div>
    )


export const getStaticProps: GetStaticProps = () => 
    return 
        props: 
            host: process.env.DB_HOST.toString(),
        ,
    


export default Home

【问题讨论】:

【参考方案1】:

您好,回答了您的问题,但以上答案都没有帮助我。

我快速阅读了文档: https://nextjs.org/docs/basic-features/data-fetching#getstaticprops-static-generation

并发现您的 getStaticProps 的正确类型应该是:

import  GetStaticProps  from 'next'

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

然后在你的组件中:

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

这会从 GetStaticProps 自动生成一个类型到你的组件,它对我有用 100%

【讨论】:

【参考方案2】:

您的原始示例几乎是正确的,但 getStaticProps 函数表达式缺少 async。试试这个:

export const getStaticProps: GetStaticProps = async () =>  // must be async
  return 
    props: 
      host: process.env.DB_HOST.toString(),
    ,
  ;
;

这不是因为TS,而是getStaticProps() in Next.js的实际定义。

回到你的例子,更好的是使用 Props 泛型改进打字:

interface Props 
  host: string;


export const getStaticProps: GetStaticProps<Props> = async () => 
  return 
    props: 
      host: process.env.DB_HOST.toString(),
    ,
  ;
;

【讨论】:

【参考方案3】:

答案如下:

export async function getStaticProps(context): Promise<GetStaticPropsResult<HomeProps>> 
    return 
        props: 
            host: process.env.DB_HOST,
        ,
    ;

我的同事通过检查 GetStaticProps 类型定义找到了解决方案:

这是整个页面的代码

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 &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"  className=styles.logo />
                </a>
            </footer>
        </div>
    );
;

export async function getStaticProps(context): Promise<GetStaticPropsResult<HomeProps>> 
    return 
        props: 
            host: process.env.DB_HOST,
        ,
    ;


export default Home;

【讨论】:

【参考方案4】:

简而言之,将其用于持续重用:


export const getStaticProps = async (
    params,
: GetStaticPropsContext<PageParams>): Promise<
    GetStaticPropsResult<ContentPageProps>
> => 
    const  title, description  = await fetch(".../entity",  uuid: params.uuid )
    return 
        props: 
            title,
            description,
        ,
    

对于我来说,getStaticPropspage/content.tsx 中的正确输入如下所示:

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,
    

通知

async (context:GetStaticPropsContext<PageParams>):
    Promise<GetStaticPropsResult<ContentPageProps>

PageParams 派生自 ParsedUrlQueryContentPageProps 是您将放入组件中进行渲染的内容,可以任意复杂度(但不能递归)。

【讨论】:

时机无可挑剔 @petrosmm 很高兴它有帮助 export default const ContentPage 这显然是一个错误,而且只有一个。只需 export default ContentPage 之前的任务【参考方案5】:

我遇到了和 OP 一样的麻烦。本教程非常适合我:https://www.vitamindev.com/next-js/getstaticprops-getstaticpaths-typescript/。它解决了getStaticPaths 需要ParsedUrlQuery 类型的问题。作者提供扩展它,作为一种解决方案。请准确命名您的属性(!)否则 TS 会抱怨。

【讨论】:

以上是关于如何使 Next.js getStaticProps 与打字稿一起使用的主要内容,如果未能解决你的问题,请参考以下文章

错误:如何从 getStaticProps 序列化数据:Next.js

如何在 Next.js 中调试 getStaticProps(和 getStaticPaths)

Next.js:如何从 getStaticProps 中获取静态资产

Next.js:如何将 getStaticProps/getStaticPaths 用于具有多个域/主机名的站点?

Next.js withPageAuthRequired 和 getStaticProps

Next.JS Redux 调度在 getStaticProps() 中不起作用