Строгая типизация навигации

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

Определение маршрутов с типами

Маршруты в TanStack Router создаются с помощью функции createRouter и структурируются в дерево маршрутов. Каждый маршрут можно типизировать через интерфейсы для параметров и данных:

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

interface UserParams {
  userId: string;
}

interface UserData {
  name: string;
  age: number;
}

const userRoute = new Route({
  path: '/user/:userId',
  component: UserComponent,
  validateParams: (params): params is UserParams => typeof params.userId === 'string',
  loader: async ({ params }) => {
    const data = await fetchUser(params.userId);
    return data as UserData;
  }
});

Ключевые моменты:

  • validateParams гарантирует, что параметры соответствуют ожидаемой структуре.
  • loader возвращает строго типизированные данные, которые можно использовать в компоненте без дополнительных проверок типов.

Типизация навигации

Функции навигации (navigate, router.go, router.replace) поддерживают строгую типизацию параметров. Параметры маршрутов и query-параметры проверяются на этапе компиляции:

router.navigate({
  to: userRoute,
  params: { userId: '123' },
  search: { showDetails: 'true' }
});

Любая попытка передать лишние или неверные типы параметров вызовет ошибку компиляции.

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

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

const userSettingsRoute = new Route({
  path: 'settings',
  parent: userRoute,
  component: UserSettingsComponent,
  loader: async ({ parentData }) => {
    return fetchSettings(parentData.userId);
  }
});
  • parentData содержит типизированные данные родительского маршрута.
  • Ошибки типа будут выявлены при обращении к свойствам parentData, если структура данных не соответствует ожидаемой.

Интеграция с React и хуки

При использовании React-компонентов TanStack Router предлагает хук useRouteLoaderData для доступа к типизированным данным маршрута:

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

function UserComponent() {
  const user = useRouteLoaderData();
  return (
    

{user.name}

Возраст: {user.age}

); }

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

Типизация динамических маршрутов и query-параметров

Для маршрутов с динамическими сегментами и query-параметрами используется комбинация Params и Search типов:

interface SearchParams {
  query: string;
  page?: number;
}

const searchRoute = new Route({
  path: '/search',
  component: SearchComponent,
  validateSearch: (search): search is SearchParams => typeof search.query === 'string'
});
  • Необязательные параметры можно отмечать через ?.
  • Типы query-параметров проверяются при навигации, исключая возможность ошибок при построении URL.

Типизация переходов с передачей состояния

TanStack Router поддерживает передачу состояния через объект state, который также может быть типизирован:

interface ModalState {
  fromDashboard: boolean;
}

router.navigate({
  to: modalRoute,
  state: { fromDashboard: true } as ModalState
});
  • Типизированное состояние позволяет использовать строгую проверку при доступе через useLocation или useRouteState.

Выводы по строгой типизации

Строгая типизация в TanStack Router обеспечивает:

  • Безопасность навигации без runtime-ошибок.
  • Автодополнение и проверку типов в редакторе.
  • Надёжную работу с вложенными маршрутами, параметрами и данными.
  • Возможность безопасной передачи состояния и query-параметров.

Эти механизмы делают маршрутизацию более предсказуемой и упрощают масштабирование больших приложений на TypeScript, предотвращая большинство типовых ошибок, связанных с маршрутизацией и доступом к данным.