如何使 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 →</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" 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 →</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" 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,
,
对于我来说,getStaticProps
在page/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
派生自 ParsedUrlQuery
,ContentPageProps
是您将放入组件中进行渲染的内容,可以任意复杂度(但不能递归)。
【讨论】:
时机无可挑剔 @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 用于具有多个域/主机名的站点?