tRPCMiddleTechnical

Что такое тип AppRouter и как его экспортировать для использования на клиенте?

AppRouter — это TypeScript-тип, выведенный из корневого роутера tRPC через typeof router. Экспортируется из серверного файла и импортируется клиентом только как тип (import type), без переноса серверного кода в бандл.

Что такое тип AppRouter

AppRouter — это TypeScript-тип, который описывает полную структуру вашего tRPC API: все роутеры, процедуры, входные и выходные типы. Он выводится из переменной корневого роутера с помощью оператора typeof. Именно через этот тип клиент «знает» обо всех доступных эндпоинтах без единого HTTP-запроса во время сборки.

Как определить и экспортировать AppRouter

В серверном файле (например, server/trpc/router.ts) создайте роутер и сразу экспортируйте его тип:

// server/trpc/router.ts
import { initTRPC } from '@trpc/server';
import { z } from 'zod';

const t = initTRPC.create();

const userRouter = t.router({
  getById: t.procedure
    .input(z.object({ id: z.string() }))
    .query(({ input }) => {
      return { id: input.id, name: 'Alice' };
    }),
});

export const appRouter = t.router({
  user: userRouter,
});

// Экспортируем ТИП — не значение!
export type AppRouter = typeof appRouter;

Как использовать тип на клиенте

На клиенте импортируйте AppRouter исключительно через import type. Это гарантирует, что TypeScript использует тип только для проверки — серверный код (подключение к БД, секреты) никогда не попадёт в клиентский бандл:

// lib/trpc.ts (клиентский файл)
import { createTRPCReact } from '@trpc/react-query';
import type { AppRouter } from '../server/trpc/router';

export const trpc = createTRPCReact<AppRouter>();

После этого все вызовы через trpc полностью типизированы: автодополнение в IDE подсказывает имена процедур, типы аргументов и структуру ответа.

Подводные камни

  • Использование import { AppRouter } вместо import type { AppRouter } может случайно втянуть серверный код в клиентский бандл — всегда используйте import type.
  • Если серверный файл содержит обращения к БД или Node.js-only модулям (fs, crypto), ошибка сборки появится немедленно при неправильном импорте.
  • Тип AppRouter не содержит реализации — нельзя вызвать его методы напрямую, только через клиент tRPC.
  • При использовании monorepo убедитесь, что серверный пакет не попадает в зависимости клиентского бандла через bundleDependencies или некорректные aliases.
  • Переименование процедур на сервере ломает клиентский код сразу при компиляции — это особенность, а не баг: TypeScript явно укажет на все затронутые места.
  • Глубоко вложенные роутеры (appRouter.a.b.c.procedure) увеличивают время вывода типов; при большом API это может замедлить TypeScript Language Server.
  • В Next.js App Router нельзя импортировать AppRouter в Server Components напрямую с серверной логикой — используйте createCallerFactory для прямых вызовов на сервере.

Common mistakes

  • Смешивать «AppRouter» с похожим механизмом без критерия выбора.
  • Игнорировать риск: неверно оценить границы применения темы «AppRouter» и получить хрупкое решение.
  • Показывать только синтаксис и не объяснять поведение в runtime или сборке.

What the interviewer is testing

  • Объясняет экспорт типа корневого router для клиентского inference.
  • Показывает на примере, как работает: AppRouter должен быть typeof appRouter и экспортироваться как type, чтобы клиент не потянул серверный runtime-код в браузерный bundle.
  • Называет production-нюанс и граничный случай для темы «AppRouter».

Sources

Related topics