Типизация параметров и данных

TanStack Router предоставляет мощный и гибкий способ работы с маршрутизацией в современных приложениях на JavaScript и TypeScript. Одной из ключевых особенностей является возможность строгой типизации параметров маршрутов и данных, что значительно повышает надёжность и предсказуемость кода.


Типизация параметров маршрута

Параметры маршрута (params) определяются как динамические сегменты URL, например /users/:userId. В TanStack Router они могут быть строго типизированы с использованием TypeScript, что позволяет избежать ошибок при доступе к параметрам.

import { createRouter, createRoute } from '@tanstack/router';

const userRoute = createRoute({
  path: '/users/:userId',
  component: UserComponent,
  // Типизация параметров
  params: {} as { userId: string },
});

В этом примере userId будет строго восприниматься как строка. При попытке передать число или любой другой тип TypeScript выдаст ошибку ещё на этапе компиляции.

Доступ к параметрам

Для получения параметров маршрута используется хук useParams:

import { useParams } from '@tanstack/router';

function UserComponent() {
  const { userId } = useParams<typeof userRoute>();
  // userId имеет тип string
}

Типизация через typeof userRoute обеспечивает автоматическое наследование типов и защищает от ошибок при рефакторинге маршрутов.


Типизация поисковых параметров (query)

Поисковые параметры URL (query) также могут быть строго типизированы. Это особенно важно при работе с фильтрацией, пагинацией или любыми динамическими данными в URL.

const usersRoute = createRoute({
  path: '/users',
  component: UsersComponent,
  search: {} as { page?: number; filter?: string },
});

Доступ к поисковым параметрам осуществляется через хук useSearch:

import { useSearch } from '@tanstack/router';

function UsersComponent() {
  const { page, filter } = useSearch<typeof usersRoute>();
  // page имеет тип number | undefined
  // filter имеет тип string | undefined
}

Использование строгой типизации позволяет корректно обрабатывать значения и уменьшает количество runtime-ошибок.


Типизация данных маршрута (loader и action)

TanStack Router поддерживает загрузку данных на уровне маршрута через loader и отправку данных через action. Типизация этих данных позволяет точно определить, какие данные ожидаются и возвращаются.

const userRoute = createRoute({
  path: '/users/:userId',
  component: UserComponent,
  loader: async ({ params }) => {
    const response = await fetch(`/api/users/${params.userId}`);
    return response.json() as Promise<{ id: string; name: string }>;
  },
});

Типизация данных обеспечивается с помощью TypeScript, что позволяет в компоненте использовать данные с полной информацией о типах:

import { useLoaderData } from '@tanstack/router';

function UserComponent() {
  const data = useLoaderData<typeof userRoute>();
  // data имеет тип { id: string; name: string }
}

Типизация вложенных маршрутов

TanStack Router поддерживает вложенные маршруты, где параметры и данные могут наследоваться от родительских маршрутов. Для сложных приложений это позволяет поддерживать строгую типизацию на всех уровнях маршрутов.

const rootRoute = createRoute({ path: '/' });

const usersRoute = createRoute({
  path: 'users',
  parent: rootRoute,
  search: {} as { page?: number },
});

const userDetailRoute = createRoute({
  path: ':userId',
  parent: usersRoute,
  loader: async ({ params }) => fetchUser(params.userId),
});

Использование typeof на каждом уровне маршрута позволяет автоматически подтягивать типы параметров и данных родительских маршрутов:

function UserDetailComponent() {
  const params = useParams<typeof userDetailRoute>();
  const search = useSearch<typeof usersRoute>();
  const user = useLoaderData<typeof userDetailRoute>();
}

Типизация действий (actions)

Actions используются для обработки форм и других интерактивных событий. Они могут быть строго типизированы по входным и выходным данным.

const updateUserAction = createRoute({
  path: '/users/:userId/edit',
  action: async ({ params, formData }) => {
    const response = await fetch(`/api/users/${params.userId}`, {
      method: 'POST',
      body: JSON.stringify(formData),
    });
    return response.json() as Promise<{ success: boolean }>;
  },
});

Хук useAction обеспечивает безопасное использование типизированных данных:

const { run } = useAction<typeof updateUserAction>();
await run({ name: 'New Name' });

Практические рекомендации по типизации

  • Использовать typeof route для автоматического наследования типов.
  • Всегда указывать типы для params, search, loader и action.
  • При работе с вложенными маршрутами комбинировать типы родителя и дочернего маршрута.
  • Типизация данных и параметров снижает риск ошибок при рефакторинге и позволяет полностью использовать возможности TypeScript.

Типизация параметров и данных в TanStack Router создаёт мощную основу для безопасной маршрутизации в приложениях. Она обеспечивает строгий контроль типов на всех уровнях, от динамических сегментов URL до данных, загружаемых асинхронно, и действий, выполняемых пользователем.