Menu

TypeScript

Next.js 内置了 TypeScript 支持,当你使用 create-next-app 创建新项目时,会自动安装必要的包并配置适当的设置。

要将 TypeScript 添加到现有项目中,只需将文件重命名为 .ts / .tsx。运行 next devnext build 会自动安装必要的依赖项,并添加一个带有推荐配置选项的 tsconfig.json 文件。

值得注意的是:如果你已经有一个 jsconfig.json 文件,请将旧 jsconfig.json 中的 paths 编译器选项复制到新的 tsconfig.json 文件中,然后删除旧的 jsconfig.json 文件。

IDE 插件

Next.js 包含一个自定义 TypeScript 插件和类型检查器,VSCode 和其他代码编辑器可以使用它进行高级类型检查和自动完成。

你可以在 VS Code 中通过以下方式启用该插件:

  1. 打开命令面板(Ctrl/⌘ + Shift + P
  2. 搜索"TypeScript: Select TypeScript Version"
  3. 选择"Use Workspace Version"
TypeScript Command Palette

现在,在编辑文件时,自定义插件将被启用。当运行 next build 时,自定义类型检查器将被使用。

TypeScript 插件可以帮助:

  • 当为 segment 配置选项 传递无效值时发出警告。
  • 显示可用选项和上下文文档。
  • 确保正确使用 use client 指令。
  • 确保客户端钩子(如 useState)只在客户端组件中使用。

🎥 观看: 了解内置 TypeScript 插件 → YouTube(3 分钟)

端到端类型安全

Next.js App Router 具有增强的类型安全。这包括:

  1. 获取函数和页面之间无数据序列化:你可以在服务器上的组件、布局和页面中直接 fetch 数据。这些数据不需要被序列化(转换为字符串)后传递给客户端使用。相反,由于 app 默认使用服务器组件,我们可以直接使用 DateMapSet 等值,无需额外步骤。以前,你需要使用 Next.js 特定类型手动为服务器和客户端之间的边界添加类型。
  2. 组件之间的简化数据流:通过用根布局替代 _app,现在更容易可视化组件和页面之间的数据流。以前,在各个 pages_app 之间流动的数据难以添加类型,并可能引入令人困惑的 bug。使用 App Router 中的 共置数据获取,这不再是问题。

Next.js 中的数据获取现在提供了尽可能接近端到端类型安全的方式,而不对你的数据库或内容提供商选择做出规定。

我们可以像在正常 TypeScript 中一样为响应数据添加类型。例如:

app/page.tsx
TypeScript
async function getData() {
  const res = await fetch('https://api.example.com/...')
  // 返回值不会被序列化
  // 你可以返回 Date、Map、Set 等
  return res.json()
}
 
export default async function Page() {
  const name = await getData()
 
  return '...'
}

要实现完全的端到端类型安全,还需要你的数据库或内容提供商支持 TypeScript。这可以通过使用 ORM 或类型安全的查询构建器来实现。

示例

类型检查 next.config.ts

你可以在 Next.js 配置中使用 TypeScript 并导入类型,方法是使用 next.config.ts

next.config.ts
import type { NextConfig } from 'next'
 
const nextConfig: NextConfig = {
  /* 这里是配置选项 */
}
 
export default nextConfig

值得注意的是:目前 next.config.ts 中的模块解析仅限于 CommonJS。这可能会导致与在 next.config.ts 中加载的仅 ESM 包不兼容的问题。

当使用 next.config.js 文件时,你可以使用 JSDoc 在 IDE 中添加一些类型检查,如下所示:

next.config.js
// @ts-check
 
/** @type {import('next').NextConfig} */
const nextConfig = {
  /* 这里是配置选项 */
}
 
module.exports = nextConfig

静态类型链接

Next.js 可以静态类型化链接,以防止在使用 next/link 时出现拼写错误和其他错误,提高导航页面时的类型安全性。

要选择使用此功能,需要启用 experimental.typedRoutes 并且项目需要使用 TypeScript。

next.config.ts
import type { NextConfig } from 'next'
 
const nextConfig: NextConfig = {
  experimental: {
    typedRoutes: true,
  },
}
 
export default nextConfig

Next.js 将在 .next/types 中生成一个链接定义,其中包含有关应用程序中所有现有路由的信息,TypeScript 可以使用这些信息在你的编辑器中提供有关无效链接的反馈。

目前,实验性支持包括任何字符串字面量,包括动态段。对于非字面量字符串,你目前需要手动将 href 转换为 as Route

import type { Route } from 'next';
import Link from 'next/link'
 
// 如果 href 是有效路由,则没有 TypeScript 错误
<Link href="/about" />
<Link href="/blog/nextjs" />
<Link href={`/blog/${slug}`} />
<Link href={('/blog' + slug) as Route} />
 
// 如果 href 不是有效路由,则出现 TypeScript 错误
<Link href="/aboot" />

要在包装 next/link 的自定义组件中接受 href,请使用泛型:

import type { Route } from 'next'
import Link from 'next/link'
 
function Card<T extends string>({ href }: { href: Route<T> | URL }) {
  return (
    <Link href={href}>
      <div>My Card</div>
    </Link>
  )
}

它是如何工作的?

当运行 next devnext build 时,Next.js 会在 .next 内生成一个隐藏的 .d.ts 文件,其中包含有关应用程序中所有现有路由的信息(所有作为 Linkhref 类型的有效路由)。此 .d.ts 文件包含在 tsconfig.json 中,TypeScript 编译器将检查该 .d.ts 并在你的编辑器中提供有关无效链接的反馈。

与异步服务器组件

要在 TypeScript 中使用 async 服务器组件,请确保你使用的是 TypeScript 5.1.3 或更高版本以及 @types/react 18.2.8 或更高版本。

如果你使用的是较旧版本的 TypeScript,可能会看到 'Promise<Element>' is not a valid JSX element 类型错误。更新到最新版本的 TypeScript 和 @types/react 应该可以解决此问题。

增量类型检查

v10.2.1 开始,Next.js 支持增量类型检查,当在你的 tsconfig.json 中启用时,这可以帮助加速大型应用程序中的类型检查。

在生产环境中禁用 TypeScript 错误

当你的项目中存在 TypeScript 错误时,Next.js 会使你的生产构建next build)失败。

如果你希望 Next.js 在应用程序有错误时仍然危险地生成生产代码,你可以禁用内置类型检查步骤。

如果禁用了类型检查,请确保你在构建或部署过程中运行类型检查,否则这可能非常危险。

打开 next.config.ts 并在 typescript 配置中启用 ignoreBuildErrors 选项:

next.config.ts
import type { NextConfig } from 'next'
 
const nextConfig: NextConfig = {
  typescript: {
    // !! 警告 !!
    // 危险地允许生产构建成功完成,即使
    // 你的项目有类型错误。
    // !! 警告 !!
    ignoreBuildErrors: true,
  },
}
 
export default nextConfig

值得注意的是:你可以在构建前运行 tsc --noEmit 来自己检查 TypeScript 错误。这对于在部署前检查 TypeScript 错误的 CI/CD 管道很有用。

自定义类型声明

当你需要声明自定义类型时,你可能会想要修改 next-env.d.ts。但是,这个文件是自动生成的,所以你做的任何更改都会被覆盖。相反,你应该创建一个新文件,比如叫 new-types.d.ts,并在你的 tsconfig.json 中引用它:

tsconfig.json
{
  "compilerOptions": {
    "skipLibCheck": true
    //...省略...
  },
  "include": [
    "new-types.d.ts",
    "next-env.d.ts",
    ".next/types/**/*.ts",
    "**/*.ts",
    "**/*.tsx"
  ],
  "exclude": ["node_modules"]
}

版本变更

版本变更
v15.0.0为 TypeScript 项目添加了 next.config.ts 支持。
v13.2.0静态类型链接处于测试阶段。
v12.0.0现在默认使用 SWC 来编译 TypeScript 和 TSX,以加快构建速度。
v10.2.1当在你的 tsconfig.json 中启用时,添加了增量类型检查支持。