Rutas con tipos
Tipos generados y paso seguro de parámetros entre pantallas. Las rutas con tipos convierten tu sistema de archivos app/ en una unión TypeScript Href - las rutas inválidas fallan en tsc antes de que se envíen.
Busca en todas las páginas de la documentación
Tipos generados y paso seguro de parámetros entre pantallas. Las rutas con tipos convierten tu sistema de archivos app/ en una unión TypeScript Href - las rutas inválidas fallan en tsc antes de que se envíen.
Tarjeta de referencia rápida - lista para copiar y pegar.
// app.config.ts
export default {
experiments: {
typedRoutes: true,
},
} satisfies import("expo/config").ExpoConfig;# Regenera tipos después de añadir rutas
npx expo start
# o
npm run typecheck # tsc --noEmitimport { Link, router, type Href } from "expo-router";
// ✅ Ruta estática - href de cadena
const settings: Href = "/settings";
// ✅ Ruta dinámica - objeto con parámetros
const order: Href = { pathname: "/orders/[id]", params: { id: "42" } };
<Link href={order}>Abre la orden</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 },
});Cuándo usarlo:
router.push en hooks - los errores de tipografía son invisibles en tiempo de ejecucióntsc --noEmitHabilita rutas con tipos, define generadores de href, consúmelos en pantallas y valida parámetros en tiempo de ejecución.
// 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>Orden 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>Enlace de orden inválido</Text>
</View>
);
}
const { id } = parsed.data;
return (
<View style={{ padding: 16 }}>
<Text>Orden {id}</Text>
</View>
);
}// Ejemplos de fallo en tiempo de compilación (no se envíen):
// router.push("/orders"); // ❌ falta parámetros para ruta [id]
// router.push("/settigns"); // ❌ error de tipografía en ruta estática
// <Link href="/unknown" /> // ❌ la ruta no existe en app/.expo/types/router.d.ts # Generado automáticamente - no edites manualmenteapp/.expo/; CI ejecuta expo start o flujo npx expo customize tsconfig para que los tipos existan antes de tsctsconfig.json debe incluir los tipos de Expo:{
"extends": "expo/tsconfig.base",
"compilerOptions": {
"strict": true
},
"include": ["**/*.ts", "**/*.tsx", ".expo/types/**/*.ts"]
}| Tipo | Propósito |
|---|---|
Href | Unión de todos los valores href válidos para Link y router |
Href<T> | Href estrecho para una ruta específica |
| Cadenas de ruta | Unión 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 generado cuando tengas dudas[...slug].tsx generan tipos de parámetros de array o string dependiendo de la configuraciónTiempo de compilación (rutas con tipos): Errores de tipografía de desarrollador en router.push / Link
Tiempo de ejecución (Zod): Deep links, notificaciones push, URLs mal formadasLas rutas con tipos no validan entrada externa - siempre analiza useLocalSearchParams() antes de recuperar.
npx expo customize tsconfig.json # configuración inicial si es necesaria
npx expo start --non-interactive & # genera .expo/types
sleep 5
npm run typecheckAñade a las verificaciones de PR cuando app/ cambia - cambios de nombre de ruta sin hrefs actualizados rompen compilaciones ruidosamente (deseado).
Tipos obsoletos después de cambiar nombre - tsc pasa localmente con .expo/types antiguos hasta que Metro reinicia. Solución: Reinicia el servidor de desarrollo o ejecuta typecheck en CI de nuevo cada vez.
Asumir que los tipos validan payloads de notificación - push abre /orders/abc con basura de consulta extra. Solución: Zod en el límite de pantalla.
Interpolación de cadenas omite verificaciones - router.push(\/orders/${id}` as Href)derrota el sistema. **Solución:** Generadores de href de objeto sin castsas Href`.
Ruta de app de monorepo no escaneada - tipos generados para raíz de workspace incorrecta. Solución: Ejecuta Expo CLI desde el directorio del paquete de la aplicación.
Falta experiments.typedRoutes - Href se amplía a string. Solución: Habilita en app.config.ts desde el primer día.
Paquete compartido importa tipos de app - acoplamiento en la dirección incorrecta. Solución: packages/navigation exporta generadores; app posee tipos generados.
Grupos de ruta en pathname - los hrefs con tipos usan rutas de URL, no nombres de grupo (tabs). Solución: /settings no /(tabs)/settings en objetos href.
| Alternativa | Usar cuando | No usar cuando |
|---|---|---|
experiments.typedRoutes | Aplicaciones Expo Router en SDK 57 | Codebases de React Navigation no-Expo |
Objeto const de routes.ts manual | Aplicaciones pequeñas (<8 rutas) | Árboles app/ de rápido crecimiento |
| Validación solo con Zod | Brownfield sin tipos | Greenfield - añade rutas con tipos también |
| Generación de código desde rutas OpenAPI | Backend-driven web parity | Mobile-first file-based routing |
ESLint no-restricted-syntax en string push | Cumplimiento de migración | Ya tienes rutas con tipos habilitadas |
// app.config.ts
experiments: { typedRoutes: true }Reinicia Metro. Confirma que .expo/types/router.d.ts existe. Ejecuta tsc --noEmit.
.expo/types/router.d.ts - generado automáticamente desde archivos en app/. No edites manualmente; reinicia el servidor de desarrollo después de cambios de ruta.
Tipos generados actualizados - los hrefs de cadena existentes pueden ser ahora inválidos. Actualiza los sitios de llamada para usar la nueva ruta o añade params ausentes para segmentos dinámicos.
Sí - grupos como (tabs) se omiten de los tipos de URL. /settings es válido; /(tabs)/settings típicamente no está en la unión Href.
const { id } = useLocalSearchParams<{ id: string }>();Los tipos generados también pueden exportar mapas de parámetros específicos de ruta - inspecciona router.d.ts. Aún así valida con Zod para puntos de entrada externos.
Sí - ejecuta generación de tipos por paquete de app (apps/mobile). Comparte funciones generadoras de href desde packages/navigation; cada app valida contra su propio árbol app/.
app/docs/[...slug].tsx genera tipos href que requieren slug - frecuentemente string | string[]. Prueba deep links con múltiples segmentos en flujos de humo de Maestro.
Evita casts as Href - silencian errores reales. Corrige la ruta o usa la forma de objeto con parámetros requeridos.
No - los tipos son solo en tiempo de compilación. Costo cero de JS en producción.
Las características importan orderDetailHref desde @/navigation/hrefs - nunca importes desde .expo/types directamente. El tipo de retorno del generador es Href.
Link, router, y prefetch[id]Redirect href con tipostsc --noEmit en CIVersiones de Stack: Esta página fue escrita para React 19.2.3, React Native 0.86.0, y Expo SDK 57 (
expo~57.0.4).
Revisado por Chris St. John·Última actualización: 16 jul 2026