TanStack Router — это современный инструмент для маршрутизации в приложениях на JavaScript и TypeScript, предоставляющий удобные возможности для работы с типами маршрутов и параметров. Одной из ключевых функций является автоматическая генерация типов, которая обеспечивает строгую типизацию навигации и данных, передаваемых через маршруты, без необходимости ручного описания интерфейсов.
В TanStack Router каждый маршрут может быть описан через объект
Route, который содержит ключевые свойства:
path, component, loader,
action и children. Основное преимущество
TypeScript-совместимой маршрутизации заключается в том, что библиотека
выводит типы параметров и состояний автоматически,
используя структуру маршрутов.
Пример определения маршрута с типизацией параметров:
import { createRouter, Route } from '@tanstack/router';
const userRoute = new Route({
path: '/user/:userId',
component: UserPage,
loader: async ({ params }) => {
const response = await fetch(`/api/users/${params.userId}`);
return response.json();
},
});
В этом примере params.userId автоматически получает тип
string, и TypeScript будет проверять его использование во
всём приложении. Это устраняет необходимость вручную описывать
интерфейсы параметров для каждого маршрута.
TanStack Router поддерживает иерархические маршруты, и при этом дочерние маршруты наследуют типизацию от родительских. Это позволяет безопасно обращаться к параметрам, переданным через URL или контекст.
const rootRoute = new Route({ path: '/' });
const userRoute = new Route({
getParentRoute: () => rootRoute,
path: 'user/:userId',
component: UserPage,
});
const settingsRoute = new Route({
getParentRoute: () => userRoute,
path: 'settings',
component: UserSettingsPage,
});
В дочернем маршруте settingsRoute TypeScript
автоматически понимает, что существует params.userId,
доступный из родителя, и можно использовать его без дополнительного
определения типов.
loader и action — это функции, асинхронно
загружающие данные или обрабатывающие действия. Типизация этих функций
также выводится автоматически.
const postRoute = new Route({
path: '/posts/:postId',
component: PostPage,
loader: async ({ params }) => {
const res = await fetch(`/api/posts/${params.postId}`);
const data: Post = await res.json();
return data;
},
});
Тип data автоматически доступен в компоненте
PostPage через хук
useLoaderData<typeof postRoute>, что обеспечивает
строгую типизацию данных без ручного описания пропсов.
Одним из сильных инструментов является хук useNavigate и
метод router.navigate. Благодаря автоматической генерации
типов, передача параметров при навигации строго
проверяется.
const router = createRouter({ routes: [rootRoute, userRoute, settingsRoute] });
// корректная навигация
router.navigate({ to: userRoute.id, params: { userId: '123' } });
// ошибка компиляции: отсутствует required param
router.navigate({ to: userRoute.id });
TypeScript выдаст ошибку, если требуется обязательный параметр
userId, но он не был передан.
TanStack Router умеет выводить типы
query-параметров, если они описаны через
searchSchema или parseSearch. Это позволяет
безопасно получать параметры из URL и сразу использовать их с
корректными типами.
import { z } from 'zod';
const postsRoute = new Route({
path: '/posts',
component: PostsPage,
searchSchema: z.object({
filter: z.string().optional(),
page: z.number().default(1),
}),
});
После этого в компоненте PostsPage хук
useSearch возвращает объект строго типизированный по схеме
z.object({ filter?: string; page: number }).
Вложенные маршруты создают структуру, где типы параметров накапливаются:
const root = new Route({ path: '/' });
const blog = new Route({ getParentRoute: () => root, path: 'blog/:blogId' });
const post = new Route({ getParentRoute: () => blog, path: 'post/:postId' });
В компоненте маршрута post TypeScript знает, что
доступны:
params.blogIdparams.postIdи любые query-параметры, описанные в searchSchema на
любом уровне.
useLoaderData и
router.navigate.Автоматическая генерация типов в TanStack Router делает маршрутизацию строго типизированной, безопасной и предсказуемой, полностью используя возможности TypeScript для предотвращения ошибок на этапе компиляции. Это особенно важно в больших приложениях с множеством вложенных маршрутов и асинхронной загрузкой данных.