Типы и интерфейсы

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


Типы маршрутов

Каждый маршрут в TanStack Router описывается объектом с обязательными и необязательными полями. Основные свойства маршрута включают:

  • path — строка с шаблоном пути. Может содержать динамические сегменты, например /users/:userId.
  • component — React-компонент или функция, которая будет рендериться для данного маршрута.
  • loader — функция, возвращающая данные перед рендером компонента. Позволяет типизировать данные, загружаемые маршрутом.
  • children — массив вложенных маршрутов, что позволяет строить иерархическую структуру.

Пример базового маршрута с типами:

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

interface UserLoaderData {
  id: string;
  name: string;
}

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

Ключевой момент: типы параметров и данных загрузчика (loader) обеспечивают строгую проверку и автодополнение.


Параметры маршрутов

TanStack Router поддерживает два типа параметров:

  1. Динамические сегменты пути Определяются с помощью :paramName. Доступ к ним осуществляется через объект params в loader или компоненте.

  2. Query-параметры Определяются через интерфейсы, например searchParams. Типизация query-параметров позволяет безопасно работать с любыми фильтрами и сортировками.

Пример типизации query-параметров:

interface UsersQuery {
  page: number;
  sort?: 'asc' | 'desc';
}

const usersRoute: Route<UsersQuery, User[]> = {
  path: '/users',
  component: UsersList,
  loader: async ({ searchParams }) => {
    const page = searchParams.page || 1;
    const sort = searchParams.sort || 'asc';
    const response = await fetch(`/api/users?page=${page}&sort=${sort}`);
    return response.json();
  }
};

Ключевой момент: использование интерфейсов для query-параметров позволяет избежать ошибок при передаче неправильных типов данных.


Интерфейсы для контекста маршрута

TanStack Router позволяет создавать собственные контексты маршрутов через типизированные context объекты. Контекст доступен всем дочерним маршрутам и позволяет безопасно передавать данные между уровнями маршрутизации.

interface AuthContext {
  user: { id: string; name: string } | null;
  isAuthenticated: boolean;
}

const authContextRoute: Route<{}, {}, AuthContext> = {
  path: '/dashboard',
  component: Dashboard,
  context: { user: null, isAuthenticated: false }
};

Ключевой момент: типизация контекста повышает безопасность передачи данных между компонентами и снижает вероятность runtime-ошибок.


Типы для навигации

TanStack Router предоставляет типизированные утилиты для навигации:

  • router.navigate({ to, params, searchParams }) — безопасный переход с проверкой типов для динамических сегментов и query-параметров.
  • useMatch(route) — возвращает типизированный объект маршрута и загруженные данные.

Пример безопасной навигации:

router.navigate({
  to: '/users/:userId',
  params: { userId: '123' },
  searchParams: { page: 2 }
});

Ошибки в типах параметров или query-параметров будут выявлены на этапе компиляции, предотвращая runtime-баги.


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

Вложенные маршруты создаются через массив children и позволяют строить сложные UI с несколькими уровнями навигации. Типизация вложенных маршрутов наследуется от родительского маршрута, что обеспечивает согласованность данных и контекста.

const appRoute: Route<{}, {}> = {
  path: '/',
  component: App,
  children: [
    {
      path: 'users',
      component: UsersList,
      children: [
        {
          path: ':userId',
          component: UserProfile,
          loader: async ({ params }) => fetch(`/api/users/${params.userId}`).then(r => r.json())
        }
      ]
    }
  ]
};

Ключевой момент: типы params и loader автоматически расширяются вниз по иерархии маршрутов.


Расширение интерфейсов маршрутов

TanStack Router поддерживает расширение стандартных интерфейсов для внедрения собственных типов:

  • RouteMeta — дополнительная информация для маршрута (например, права доступа, заголовки страницы).
  • LoaderData — тип данных, возвращаемых функцией загрузки.
  • SearchParams — типизация query-параметров.

Пример с расширенным meta:

interface UserRouteMeta {
  requiresAuth: boolean;
}

const secureUserRoute: Route<{}, UserLoaderData, {}, UserRouteMeta> = {
  path: '/users/:userId',
  component: UserComponent,
  meta: { requiresAuth: true }
};

Это позволяет создавать динамическую маршрутизацию с проверкой прав доступа на уровне типов.


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