Capítulo 4 de 57
TanStack Router's unusual developer experience decisions (route configuration boilerplate, module declaration for the router instance, and a preference for file-based routing) all exist to maximize TypeScript's inference capabilities without sacrificing control or maintainability, tracing back to its origin at Nozzle.io where type-safe URL search params were a hard requirement.
<Route path="/posts" component={...} />) are rejected because TypeScript cannot infer route configuration types from them, which would break typesafe Link/navigate.getParentRoute: Each route created via createRoute must supply a getParentRoute function returning its parent, so the child route can correctly infer parent context, path params, and search params; this is a common point of failure if done incorrectly.Router instance everywhere (which bloats bundles and gets cumbersome), the recommended approach is declaring a Register interface via TypeScript module augmentation once, enabling router-aware autocomplete (e.g. in Link) app-wide without imports.getParentRoute), and automatic code-splitting of route components.// src/app.tsx
declare module '@tanstack/react-router' {
interface Register {
router: typeof router
}
}
Link/navigate without importing the router instance.// src/routes/posts/index.ts
import { createFileRoute } from '@tanstack/react-router'
export const Route = createFileRoute('/posts/')({
component: () => 'Posts index component goes here!!!',
})
getParentRoute, stitch the route tree, or code-split, compared to the equivalent code-based route.createRoute + getParentRoute) or file-based routing instead.declare module '@tanstack/react-router' { interface Register { router: typeof router } }) rather than importing it into every component.