Menu

TypeScript

Next.js 为构建 React 应用提供了以 TypeScript 为先的开发体验。

它内置了 TypeScript 支持,可以自动安装必要的包并配置适当的设置。

同时还为你的编辑器提供了 TypeScript 插件

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

新项目

create-next-app 现在默认采用 TypeScript。

Terminal
npx create-next-app@latest

现有项目

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

如果你之前有一个 jsconfig.json 文件,请将旧的 jsconfig.json 中的 paths 编译器选项复制到新的 tsconfig.json 文件中,然后删除旧的 jsconfig.json 文件。

我们还建议你使用 next.config.ts 而不是 next.config.js,以获得更好的类型推断。

TypeScript 插件

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

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

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

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

插件功能

TypeScript 插件可以帮助:

  • 对传入无效的 段配置选项 值发出警告。
  • 显示可用选项和上下文文档。
  • 确保正确使用 use client 指令。
  • 确保客户端 hook (如 useState) 只在客户端组件中使用。

小贴士:未来将添加更多功能。

最低 TypeScript 版本

强烈建议使用至少 v4.5.2 版本的 TypeScript,以获得诸如 导入名称的类型修饰符性能改进 等语法功能。

Next.js 配置中的类型检查

对 next.config.js 进行类型检查

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

next.config.js
// @ts-check
 
/** @type {import('next').NextConfig} */
const nextConfig = {
  /* 在此处添加配置选项 */
};
 
module.exports = nextConfig;

对 next.config.ts 进行类型检查

你可以使用 TypeScript 并在 Next.js 配置中导入类型,方法是使用 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.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 文件并在你的编辑器中提供关于无效链接的反馈。

端到端类型安全

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

  1. 获取函数和页面之间无需数据序列化:你可以直接在服务器上的组件、布局和页面中进行 fetch。这些数据_无需_序列化 (转换为字符串) 就可以传递到客户端供 React 使用。相反,由于 app 默认使用服务器组件,我们可以直接使用 DateMapSet 等值,无需额外步骤。以前,你需要使用 Next.js 特定的类型手动为服务器和客户端之间的边界添加类型。

  2. 简化组件间的数据流:通过用根布局替代 _app,现在更容易可视化组件和页面之间的数据流。以前,在单个 pages_app 之间流动的数据难以添加类型,并可能引入令人困惑的 bug。使用 App Router 中的 并置数据获取,这个问题不再存在。

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

我们可以像在普通 TypeScript 中那样为响应数据添加类型。例如:

app/page.tsx
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 或类型安全的查询构建器来实现。

异步服务器组件 TypeScript 错误

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

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

在服务器和客户端组件之间传递数据

当通过 props 在服务器和客户端组件之间传递数据时,数据仍然会被序列化 (转换为字符串) 以在浏览器中使用。然而,它不需要特殊的类型。它的类型与在组件之间传递任何其他 props 相同。

此外,需要序列化的代码更少,因为未渲染的数据不会在服务器和客户端之间传递 (它保留在服务器上)。这只有通过对服务器组件的支持才成为可能。

路径别名和 baseUrl

Next.js 自动支持 tsconfig.json 中的 "paths""baseUrl" 选项。

你可以在 模块路径别名文档 中了解更多关于此功能的信息。

增量类型检查

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: {
    // !! WARN !!
    // Dangerously allow production builds to successfully complete even if
    // your project has type errors.
    // !! WARN !!
    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静态类型链接在 beta 版中可用。
v12.0.0现在默认使用 SWC 来编译 TypeScript 和 TSX,以实现更快的构建。
v10.2.1当在你的 tsconfig.json 中启用时,添加了对 增量类型检查 的支持。