TypeScript

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

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

此外还提供了适用于编辑器的 TypeScript 插件

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

新建项目

create-next-app 现在默认包含 TypeScript 支持。

终端
npx create-next-app@latest

现有项目

通过将文件重命名为 .ts / .tsx 来为项目添加 TypeScript 支持。运行 next devnext build 会自动安装必要的依赖项,并添加包含推荐配置选项的 tsconfig.json 文件。

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

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 指令
  • 确保客户端钩子(如 useState)仅在客户端组件中使用

须知:未来将添加更多功能。

TypeScript 最低版本

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

静态类型链接

Next.js 可以对链接进行静态类型检查,防止使用 next/link 时出现拼写错误和其他问题,从而提高页面导航时的类型安全性。

要启用此功能,需要开启 experimental.typedRoutes 并且项目必须使用 TypeScript。

next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
  experimental: {
    typedRoutes: true,
  },
}

module.exports = nextConfig

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

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

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>我的卡片</div>
    </Link>
  )
}

工作原理:

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

端到端类型安全

Next.js 应用路由具有 增强的类型安全性。这包括:

  1. 无需在获取函数和页面间序列化数据:您可以直接在服务器上的组件、布局和页面中 fetch。这些数据 不需要 序列化(转换为字符串)就能传递给客户端供 React 使用。由于 app 默认使用服务器组件,我们可以直接使用 DateMapSet 等值而无需额外步骤。以前,您需要使用 Next.js 特定的类型手动标注服务器和客户端之间的边界。
  2. 组件间简化的数据流:随着 _app 被根布局取代,现在更容易可视化组件和页面间的数据流。以前,单个 pages_app 之间流动的数据难以标注类型,可能会引入令人困惑的错误。通过应用路由中的 数据获取与组件同置,这不再是问题。

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" 选项。

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

检查 next.config.js 类型

next.config.js 文件必须是 JavaScript 文件,因为它不会被 Babel 或 TypeScript 解析,但您可以使用 JSDoc 在 IDE 中添加一些类型检查,如下所示:

// @ts-check

/**
 * @type {import('next').NextConfig}
 **/
const nextConfig = {
  /* 此处为配置选项 */
}

module.exports = nextConfig

增量类型检查

v10.2.1 起,Next.js 支持在 tsconfig.json 中启用 增量类型检查,这有助于在大型应用中加快类型检查速度。

忽略 TypeScript 错误

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

如果您希望 Next.js 即使在应用存在错误时也能危险地生成生产代码,可以禁用内置的类型检查步骤。

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

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

next.config.js
module.exports = {
  typescript: {
    // !! 警告 !!
    // 危险地允许生产构建在项目存在类型错误时成功完成
    // !! 警告 !!
    ignoreBuildErrors: true,
  },
}

自定义类型声明

当需要声明自定义类型时,您可能会想修改 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"]
}

版本变更

版本变更
v13.2.0静态类型链接进入测试阶段
v12.0.0默认使用 SWC 来编译 TypeScript 和 TSX 以获得更快的构建速度
v10.2.1当在 tsconfig.json 中启用时,添加了对 增量类型检查 的支持