Rotas Tipadas
Tipos gerados e passagem segura de parâmetros entre telas. Rotas tipadas transformam o seu sistema de arquivos app/ em uma união Href do TypeScript - caminhos inválidos falham tsc antes de serem enviados.
Busque em todas as páginas da documentação
Tipos gerados e passagem segura de parâmetros entre telas. Rotas tipadas transformam o seu sistema de arquivos app/ em uma união Href do TypeScript - caminhos inválidos falham tsc antes de serem enviados.
Cartão de receita de referência rápida - pronto para copiar e colar.
// app.config.ts
export default {
experiments: {
typedRoutes: true,
},
} satisfies import("expo/config").ExpoConfig;# Regenera tipos após adicionar rotas
npx expo start
# ou
npm run typecheck # tsc --noEmitimport { Link, router, type Href } from "expo-router";
// ✅ Static route - string href
const settings: Href = "/settings";
// ✅ Dynamic route - object with params
const order: Href = { pathname: "/orders/[id]", params: { id: "42" } };
<Link href={order}>Open order</Link>
router.push(order);// src/navigation/hrefs.ts
import type { Href } from "expo-router";
export const orderDetailHref = (id: string): Href => ({
pathname: "/orders/[id]",
params: { id },
});Quando usar isso:
router.push em hooks - erros de digitação são invisíveis em tempo de execuçãotsc --noEmitAtive rotas tipadas, defina construtores de href, consuma em telas e valide parâmetros em tempo de execução.
// app.config.ts
import type { ExpoConfig, ConfigContext } from "expo/config";
export default ({ config }: ConfigContext): ExpoConfig => ({
...config,
name: "TypedRoutesApp",
slug: "typed-routes-app",
experiments: {
typedRoutes: true,
},
});app/
├── _layout.tsx
├── settings.tsx
└── orders/
├── index.tsx
└── [id].tsx// src/navigation/hrefs.ts
import type { Href } from "expo-router";
export const hrefs = {
settings: "/settings" as Href,
orders: "/orders" as Href,
orderDetail: (id: string): Href => ({
pathname: "/orders/[id]",
params: { id },
}),
} as const;// features/orders/ui/OrdersListScreen.tsx
import { Link } from "expo-router";
import { Text, View } from "react-native";
import { hrefs } from "@/navigation/hrefs";
export function OrdersListScreen() {
return (
<View style={{ padding: 16 }}>
<Link href={hrefs.orderDetail("99")}>
<Text>Order 99</Text>
</Link>
</View>
);
}// features/orders/ui/OrderDetailScreen.tsx
import { useLocalSearchParams } from "expo-router";
import { z } from "zod";
import { Text, View } from "react-native";
const paramsSchema = z.object({
id: z.string().min(1),
});
export function OrderDetailScreen() {
const raw = useLocalSearchParams();
const parsed = paramsSchema.safeParse(raw);
if (!parsed.success) {
return (
<View style={{ padding: 16 }}>
<Text>Invalid order link</Text>
</View>
);
}
const { id } = parsed.data;
return (
<View style={{ padding: 16 }}>
<Text>Order {id}</Text>
</View>
);
}// Compile-time failure examples (do not ship):
// router.push("/orders"); // ❌ missing params for [id] route
// router.push("/settigns"); // ❌ typo in static path
// <Link href="/unknown" /> // ❌ route does not exist in app/.expo/types/router.d.ts # Gerado automaticamente - não editar manualmenteapp/.expo/; CI executa o fluxo expo start ou npx expo customize tsconfig para que os tipos existam antes do tsctsconfig.json deve incluir os tipos do Expo:{
"extends": "expo/tsconfig.base",
"compilerOptions": {
"strict": true
},
"include": ["**/*.ts", "**/*.tsx", ".expo/types/**/*.ts"]
}| Tipo | Propósito |
|---|---|
Href | União de todos os valores href válidos para Link e router |
Href<T> | Estreita o href para uma rota específica |
| Strings de caminho de rota | União literal de segmentos estáticos |
import type { Href } from "expo-router";
function navigate(href: Href) {
router.push(href);
}app/users/[userId]/posts/[postId].tsxconst href: Href = {
pathname: "/users/[userId]/posts/[postId]",
params: { userId: "1", postId: "9" },
};tscrouter.d.ts gerado quando tiver dúvidas[...slug].tsx geram tipos de parâmetro de array ou string dependendo da configuraçãoTempo de compilação (rotas tipadas): Erros de digitação do desenvolvedor em router.push / Link
Tempo de execução (Zod): Deep links, notificações push, URLs malformadasRotas tipadas não validam a entrada externa - sempre analise useLocalSearchParams() antes de buscar dados.
npx expo customize tsconfig.json # configuração inicial, se necessário
npx expo start --non-interactive & # gera .expo/types
sleep 5
npm run typecheckAdicione às verificações de PR quando app/ mudar - renomear rotas sem hrefs atualizados quebra as compilações ruidosamente (desejado).
Tipos desatualizados após renomear - tsc passa localmente com .expo/types antigos até o Metro reiniciar. Correção: Reinicie o servidor de desenvolvimento ou execute o typecheck em CI fresco a cada vez.
Assumir que os tipos validam payloads de notificação - push abre /orders/abc com lixo extra de consulta. Correção: Zod na fronteira da tela.
Interpolação de string contorna verificações - router.push(\/orders/${id}` as Href)derrota o sistema. **Correção:** Construtores de href de objeto sem castsas Href`.
Caminho do aplicativo monorepo não escaneado - tipos gerados para a raiz do pacote de aplicativo errada. Correção: Execute o Expo CLI a partir do diretório do pacote do aplicativo.
experiments.typedRoutes ausente - Href se alarga para string. Correção: Habilite em app.config.ts desde o primeiro dia.
Pacote compartilhado importa tipos de aplicativo - acoplamento na direção errada. Correção: packages/navigation exporta construtores; o aplicativo é proprietário dos tipos gerados.
Grupos de rotas no pathname - hrefs tipados usam caminhos de URL, não nomes de grupo (tabs). Correção: /settings não /(tabs)/settings em objetos href.
| Alternativa | Use Quando | Não Use Quando |
|---|---|---|
experiments.typedRoutes | Aplicativos Expo Router no SDK 57 | Bases de código React Navigation não-Expo |
Objeto manual routes.ts const | Aplicativos minúsculos (<8 rotas) | Árvores app/ de crescimento rápido |
| Validação apenas com Zod | Brownfield não tipado | Greenfield - adicione rotas tipadas também |
| Codegen de caminhos OpenAPI | Paridade web orientada por backend | Roteamento baseado em arquivos mobile-first |
ESLint no-restricted-syntax em push de string | Impor migração | Você já habilitou rotas tipadas |
// app.config.ts
experiments: { typedRoutes: true }Reinicie o Metro. Confirme se .expo/types/router.d.ts existe. Execute tsc --noEmit.
.expo/types/router.d.ts - gerado automaticamente a partir de arquivos em app/. Não edite manualmente; reinicie o servidor de desenvolvimento após alterações de rota.
Tipos gerados atualizados - hrefs de string existentes podem agora ser inválidos. Atualize os call sites para usar o novo caminho ou adicione params ausentes para segmentos dinâmicos.
Sim - grupos como (tabs) são omitidos dos tipos de URL. /settings é válido; /(tabs)/settings tipicamente não está na união Href.
const { id } = useLocalSearchParams<{ id: string }>();Tipos gerados também podem exportar mapas de parâmetros específicos da rota - inspecione router.d.ts. Ainda assim, valide com Zod para pontos de entrada externos.
Sim - execute a geração de tipos por pacote de aplicativo (apps/mobile). Compartilhe funções construtoras de href de packages/navigation; cada aplicativo valida contra sua própria árvore app/.
app/docs/[...slug].tsx gera tipos de href que exigem slug - frequentemente string | string[]. Teste deep links com múltiplos segmentos em fluxos de fumaça do Maestro.
Evite casts as Href - eles silenciam erros reais. Corrija o caminho ou use a forma de objeto com parâmetros obrigatórios.
Não - tipos são apenas para tempo de compilação. Custo zero de JS na produção.
Recursos importam orderDetailHref de @/navigation/hrefs - nunca importe diretamente de .expo/types. O tipo de retorno do construtor é Href.
Link, router e prefetch[id]Redirect href tipadotsc --noEmit em CIVersões da Stack: Esta página foi escrita para React 19.2.3, React Native 0.86.0 e Expo SDK 57 (
expo~57.0.4).
Revisado por Chris St. John·Última atualização: 16 de jul. de 2026