Typed routes feature overview
Expo Router supports generating TypeScript types automatically with Expo CLI, enabling `<Link>` and hooks API to be statically typed. This feature is currently in beta and is not enabled by default. It is available when using TypeScript in your project.
Quick start configuration for typed routes
If your project was created using the Expo Router quick start guide, it is already configured to use typed routes. The Expo CLI will generate the required type file the first time you run `npx expo start`, enabling autocomplete for `href` props in `<Link>` components within **.tsx** files.
Manual configuration for typed routes
To enable typed routes in an existing project, set `experiments.typedRoutes` to `true` in **app.json**. Then run `npx expo customize tsconfig.json` to configure your **tsconfig.json** with required `includes` fields. Start the development server with `npx expo start` to use autocomplete in the `<Link>` component's `href` prop.
Type generation and git configuration
Typed routes in Expo Router are automatically generated when the development server starts. The generated types are configured to be untracked by Git and will be added to the local **.gitignore** file. To generate types without starting the development server, such as on a CI server, run `npx expo customize tsconfig.json`.
Href type validation with Href<T>
The `Href<T>` type provides statically typed and strictly defined routes. Valid examples include `<Link href="/about" />`, `<Link href="/user/1" />`, `<Link href={`/user/${id}`} />`, and `<Link href={("/user" + id) as Href} />`. TypeScript will error if the href is not a valid route, such as `<Link href="/usser/1" />`.
Dynamic route href parameters with HrefObject
For dynamic routes, Href values must be objects with strictly typed parameters. Valid: `<Link href={{ pathname: "/user/[id]", params: { id: 1 }}} />`. Invalid examples include using a string path like `<Link href="/user/[id]" />`, invalid parameter keys like `{ _id: 1 }`, and unknown extra keys like `{ id: 1, id2: 2 }`.
Typed routes do not support relative paths
Statically typed routes require absolute paths for all routes. Valid: `<Link href="/about" />`. Relative paths like `<Link href="./about" />` are not supported. Use the `useSegments()` hook from `expo-router` to construct absolute paths when needed.
Using useSegments for complex relative navigation
To create complex relative paths, use the `useSegments()` hook to get the current route's first segment. For example, call `const [first] = useSegments()` to get either `(feed)` or `(search)` depending on the current tab, then navigate with `<Link href={`/${first}/profile`} />` to preserve the current tab context.
useSegments with route type parameter
You can pass a full route to `useSegments` as a generic type to get strongly typed segments. Example: `const segments = useSegments<'/(search)/profile'>()` returns `segments = ['(search)', 'profile']` with full type safety.
Imperative navigation with typed router
You can use the typed `router` object imported from `expo-router` to navigate imperatively: `router.push('/about')`. Alternatively, use the `useRouter()` hook within a component to get a typed router instance.
Strongly typed route parameters with useLocalSearchParams
To get strongly typed route parameters, pass a full route as a generic to `useLocalSearchParams` or `useGlobalSearchParams`. Example: `const { profile, search } = useLocalSearchParams<'/(search)/[profile]/[...search]'>()` types `profile` as string and `search` as string[].
Manually typing query parameters
Since query parameters are not represented in the file system, you can type them manually by passing a generic object to `useLocalSearchParams` or `useGlobalSearchParams`. Example: `const { query } = useLocalSearchParams<{ query?: string }>()` types the optional `query` parameter.
Combined route and query parameter typing
To type both route and query parameters together, pass the route as the first generic and query parameters as the second generic. Example: `useLocalSearchParams<'/[profile]/[...search]', { query?: string }>()` types both route segments and the optional query parameter.
expo-env.d.ts file generation and purpose
When typed routes is enabled, Expo CLI generates a git-ignored **expo-env.d.ts** file in your project's root directory. The file is added to **.gitignore** and included in **tsconfig.json**. It should never be removed, changed, or committed to version control.
Global types added by Expo CLI for typed routes
When typed routes is enabled, Expo CLI adds the following global types: sets `process.env.NODE_ENV = "development" | "production" | "test"`, allows importing `.[css|sass|scss]` files, sets `*.module.[css|sass|scss]` exports to `Record<string, string>`, and adds types for Metro's `require.context` for static route generation.
React Native Web augmentations with typed routes
With typed routes enabled, Expo CLI augments `react-native` types to support React Native Web by adding web-only styles to `ViewStyle`, `TextStyle`, and `ImageStyle`; adding `tabIndex`, `aria-level`, and `lang` to `TextProps`; adding `hovered` to Pressable's `children` and `style` callback function; and adding `className` support.
Route type matches all valid routes
The `Route` type is made available by `expo-router` and automatically matches all valid routes in a project. It can be used for type-safe route references.