首页指南参考教程

类型化路由

了解如何在 Expo Router 中使用静态类型的链接和路由。


在你的项目中使用 TypeScript 时可用。Expo Router 开箱即用地支持标准 TypeScript。有关如何设置的更多信息,请参阅 TypeScript 指南。

¥Available when using TypeScript in your project. Expo Router supports standard TypeScript out of the box. See the TypeScript guide for more information on how to set it up.

Expo Router 支持使用 Expo CLI 自动生成 TypeScript 类型。这使得 <Link>钩子 API 能够静态类型化。此功能目前处于测试阶段,默认情况下不启用。

¥Expo Router supports generating TypeScript types automatically with Expo CLI. This enables <Link>, and the hooks API to be statically typed. This feature is currently in beta and is not enabled by default.

开始使用

¥Get started

快速开始

¥Quick start

如果你使用 Expo 路由快速入门指南 创建项目,那么你的项目已配置为使用类型化路由。Expo CLI 将在你第一次运行 npx expo start 时生成所需的类型文件。然后,每当你在 .tsx 文件中使用 Expo Router <Link> 组件时,你都可以对 href 属性使用自动补齐功能。

¥If you created your project using the Expo Router quick start guide then your project is already configured to use typed routes. The Expo CLI will generate the required type file the first time you run npx expo start. Then, you can use autocomplete for href props whenever you use an Expo Router <Link> component in a .tsx file.

手动配置

¥Manual configuration

虽然该功能处于测试阶段,但你可以通过在 app.json 中将 experiments.typedRoutes 设置为 true 来启用它:

¥While the feature is in beta, you can enable it by setting experiments.typedRoutes to true in your app.json:

app.json
{
  "expo": {
    "experiments": {
      "typedRoutes": true
    }
  }
}

运行 npx expo customize tsconfig.json 以配置 tsconfig.json 以添加所需的 includes 字段。

¥Run npx expo customize tsconfig.json to configure your tsconfig.json to add the required includes fields.

然后,通过运行 npx expo start 启动开发服务器。你现在可以在 Expo Router <Link> 组件的 href 属性中使用自动补齐功能。

¥Then, start the development server by running npx expo start. You can now use autocomplete in the Expo Router <Link> component's href prop.

类型生成

¥Type generation

Expo Router 中的类型化路由会在开发服务器启动时自动生成。默认情况下,这些生成的类型配置为不被 Git 跟踪,并将添加到本地 .gitignore 文件中。这可以确保自动生成的文件不会扰乱你的版本控制系统。

¥Typed routes in Expo Router are automatically generated when the development server starts. By default, these generated types are configured to be untracked by Git and will be added to the local .gitignore file. This ensures that autogenerated files do not clutter your version control system.

如果你发现自己需要在不启动开发服务器的情况下生成这些类型,例如在持续集成 (CI) 服务器上进行类型检查期间。为此,请在 CI 上运行命令 npx expo customize tsconfig.json

¥If you find yourself in a situation where you need to generate these types without initiating the development server, such as during type checking on a Continuous Integration (CI) server. To do this, run the command npx expo customize tsconfig.json on the CI.

静态类型路由

¥Statically typed routes

使用 Href<T> 的组件和函数现在将是静态类型的,并且具有更严格的定义。例如:

¥Components and functions that use Href<T> will now be statically typed and have a much stricter definition. For example:

<Link href="/about" /><Link href="/user/1" /><Link href={`/user/${id}`} /><Link href={("/user" + id) as Href} />
// TypeScript errors if href is not a valid route<Link href="/usser/1" />

对于动态路由,Href 需要是对象,并且它们的参数类型严格:

¥For dynamic routes, Href's need to be objects and their parameters are strictly typed:

<Link href={{ pathname: "/user/[id]", params: { id: 1 }}} />
// TypeScript errors as href is valid, but it should be a HrefObject with params<Link href="/user/[id]" />
// TypeScript errors as params contain invalid keys<Link href={{ pathname: "/user/[id]", params: { _id: 1 }}} />
// TypeScript errors as params contain unknown keys<Link href={{ pathname: "/user/[id]", params: { id: 1, id2: 2 }}} />

相对路径

¥Relative paths

静态类型的路由不支持相对路径。你需要对所有路由使用绝对路径:

¥Statically typed routes do not support relative paths. You'll need to use absolute paths for all routes:

<Link href="/about" />

// Relative paths are not supported<Link href="./about" />

你可以利用 expo-router 中的 useSegments() 钩子来创建复杂的相对路径。考虑以下结构:

¥You can leverage the useSegments() hooks from expo-router to create complex relative paths. Consider the following structure:

app
(feed)
  _layout.tsx
  feed.tsx
  search.tsx
  profile.tsx
(search)
  profile.tsx
components
button.tsx

你可以使用 useSegments() 钩子来确保推送到同一选项卡以获取当前路由的第一段。

¥You can ensure that you push to the same tab by using the useSegments() hook to get the first segment of the current route.

button.tsx
import { Link, useSegments } from 'expo-router';

export function Button() {
  const [
    // This will be either `(feed)` or `(search)` depending on the current tab.
    first,
  ] = useSegments();

  return <Link href={`/${first}/profile`}>Push profile</Link>;
}

现在,你可以利用 app/(feed)/feed.tsx 和 app/(search)/search.tsx 中的 <Button /> 来推送 ./profile,同时保留当前选项卡。

¥Now, you can leverage <Button /> from both app/(feed)/feed.tsx and app/(search)/search.tsx to push ./profile while preserving the current tab.

命令式导航

¥Imperative navigation

你可以使用键入的 router 对象进行命令式导航:

¥You can use the typed router object to navigate imperatively:

import { router } from 'expo-router';

router.push('/about');

或者使用键入的 useRouter() 钩子:

¥Or with the typed useRouter() hook:

import { useRouter } from 'expo-router';

function Page() {
  const router = useRouter();

  router.push('/about');

  // ...
}

查询参数

¥Query parameters

大多数查询参数不会在文件系统中表示,因此无法自动键入。你可以通过将泛型传递给 useLocalSearchParamsuseGlobalSearchParams 钩子来手动键入查询参数。例如:

¥Most query parameters will not be represented in the file system and therefore cannot be typed automatically. You can type query parameters manually by passing a generic to the useLocalSearchParams and useGlobalSearchParams hooks. For example:

app/search.tsx
import { Text } from 'react-native';
import { useLocalSearchParams } from 'expo-router';

export default function Page() {
  const { query } = useLocalSearchParams<{ query?: string }>();

  return <Text>Search: {query ?? 'unset'}</Text>;
}

对环境的改变

¥Changes made to the environment

启用类型化路由后,Expo CLI 将在项目的根目录中生成 git 忽略的 expo-env.d.ts 文件,更新 .gitignore 以忽略新的根 expo-env.d.ts 文件,并修改 tsconfig。 json 以包含新的 expo-env.d.ts 文件。

¥When typed routes is enabled, Expo CLI will generate a git ignored expo-env.d.ts file in your project's root directory, update the .gitignore to ignore the new root expo-env.d.ts file, and modify the tsconfig.json to include the new expo-env.d.ts file.

tsconfig.json 中的 includes 字段已更新以包含 expo-env.d.ts 和隐藏的 .expo 目录。这些条目是必需的,不应从文件中删除。

¥The includes field in your tsconfig.json gets updated to include expo-env.d.ts and a hidden .expo directory. These entries are required and should not be removed from the file.

任何时候都不应删除或更改生成的 expo-env.d.ts。它不应该被提交并且应该被版本控制忽略。

¥The generated expo-env.d.ts should not be removed or changed at any time. It should not be committed and should be ignored by version control.

全局类型

¥Global types

当启用类型化路由时,Expo CLI 会将以下全局类型添加到你的项目中:

¥Expo CLI will add the following global types to your project when typed routes is enabled:

  • process.env.NODE_ENV = "development" | "production" | "test"

    ¥Sets process.env.NODE_ENV = "development" | "production" | "test"

  • 允许导入 .[css|sass|scss] 文件

    ¥Allows the importing of .[css|sass|scss] files

  • *.module.[css|sass|scss] 的导出设置为 Record<string, string>

    ¥Sets the exports of *.module.[css|sass|scss] to be Record<string, string>

  • 添加 Metro 的 require.context 类型。这由 expo/metro-config 启用并用于静态路由生成。

    ¥Add types for Metro's require.context. This is enabled by expo/metro-config and used for static route generation.

React Native Web

启用类型化路由后,Expo CLI 还增强了 react-native 类型以支持 React Native Web。进行了以下更改:

¥With typed routes enabled, Expo CLI also augments the react-native types to support React Native Web. The following changes are made:

  • ViewStyleTextStyleImageStyle 添加其他仅 Web 样式

    ¥Add additional web-only styles for ViewStyle, TextStyle, ImageStyle

  • tabIndexaria-levellang 添加到 TextProps

    ¥Add tabIndex, aria-level, lang to TextProps

  • Pressable 的 childrenstyle 状态回调函数中添加 hovered

    ¥Add hovered to Pressable's children and style state callback function

  • 添加 className 个元素

    ¥Add className elements

Expo 中文网 - 粤ICP备13048890号