Стратегия общего пакета типов
Создайте отдельный пакет типов, используемый во всём монорепозитории
«Стратегия общего пакета типов» — бесплатный урок TypeScript Academy на CoddyKit. Это урок 3 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения TypeScript Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс TypeScript Academy содержит 4 уроков всего.
Зачем нужен общий пакет типов
Общие типы для клиентской и серверной частей устраняют расхождения между контрактами программного интерфейса. Единый источник истины позволяет получать ошибки на этапе компиляции при изменении структуры интерфейса.
// packages/types/src/index.ts
export interface User { id: string; name: string; email: string; }
export interface ApiResponse<T> { data: T; error?: string; }Структура пакета
Сведите пакет типов к минимуму: только экспорт типов, без логики времени выполнения. Благодаря этому пакет не имеет побочных эффектов и пригоден для удаления неиспользуемого кода.
packages/types/
├── src/
│ ├── index.ts # re-exports all
│ ├── user.ts
│ ├── product.ts
│ └── api.ts
├── tsconfig.json
└── package.jsontsconfig для пакета типов
Включите emitDeclarationOnly, чтобы не создавался JavaScript, а генерировались только файлы .d.ts, на которые ссылаются потребители пакета.
{
"compilerOptions": {
"composite": true,
"declaration": true,
"emitDeclarationOnly": true,
"outDir": "./dist",
"rootDir": "./src"
}
}Использование пакета типов
Подключите пакет типов и к программному интерфейсу, и к веб-приложению, а для импорта типов используйте import type, чтобы избежать накладных расходов во время выполнения.
import type { User, ApiResponse } from "@myapp/types";
async function getUser(id: string): Promise<ApiResponse<User>> {
// ...
}Безопасная сериализация типов
Типы, общие для клиента и сервера, должны содержать только значения, сериализуемые в JSON. Избегайте объектов Date — вместо них используйте string (ISO).
// Good: serialization-safe
interface Event { id: string; createdAt: string; /* ISO date */ }
// Bad: Date is not JSON-serializable
interface Event { id: string; createdAt: Date; }Версионирование пакета типов
Версионируйте пакет типов по semver. Несовместимое изменение, например удаление или переименование поля, требует повышения мажорной версии.
# Breaking change: major bump
npm version major
# Adding optional fields: minor bump
npm version minorГенерация типов из OpenAPI
Автоматизируйте создание пакета типов, генерируя его из спецификации OpenAPI с помощью openapi-typescript. Это гарантирует постоянное соответствие типов серверной части.
npx openapi-typescript ./api/openapi.yaml -o ./packages/types/src/api.tsИспользование Zod для типов времени выполнения и компиляции
Определяйте типы с помощью схем Zod и выводите из них типы TypeScript. И проверка во время выполнения, и статические типы создаются из одного источника.
import { z } from "zod";
export const UserSchema = z.object({ id: z.string(), name: z.string() });
export type User = z.infer<typeof UserSchema>;Предотвращение циклических зависимостей
Пакет типов не должен импортировать другие пакеты рабочей области, чтобы предотвращать циклические цепочки зависимостей. Оставьте его конечным узлом графа зависимостей.
// types/ should not import from ui/ or api/
// ui/ and api/ both import from types/Проверка корректности типов
Используйте tsd для написания утверждений на уровне типов, проверяющих соответствие общих типов ожидаемым результатам.
import { expectType } from "tsd";
import type { User } from "@myapp/types";
expectType<User>({ id: "1", name: "Alice", email: "a@b.com" });Итоги: стратегия общих типов
Общий пакет типов устраняет расхождения в программном интерфейсе: создавайте только объявления, используйте типы, сериализуемые в JSON, версионируйте пакет по semver, при необходимости автоматически генерируйте его из OpenAPI и проверяйте с помощью tsd.
Быстрая проверка
Почему в общих типах программного интерфейса следует использовать string, а не Date?
Чему Вы научились
Общий пакет типов — единый источник истины для контрактов программного интерфейса. Оставляйте его предназначенным только для объявлений, безопасным для JSON, версионируйте по semver и при необходимости создавайте из OpenAPI, чтобы устранить расхождения между клиентской и серверной частями.
Часто задаваемые вопросы
Урок «Стратегия общего пакета типов» бесплатный?
Да — полный текст урока «Стратегия общего пакета типов» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс TypeScript Academy, подпишись на CoddyKit PRO. Курс TypeScript Academy содержит 4 уроков всего.
Чему я научусь в уроке «Стратегия общего пакета типов»?
Создайте отдельный пакет типов, используемый во всём монорепозитории Ты практикуешь TypeScript Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать TypeScript Academy?
Предыдущий опыт не требуется. TypeScript Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 3 из 4.
Сколько времени занимает урок «Стратегия общего пакета типов»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке TypeScript Academy?
Да. Каждый урок TypeScript Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Объяснение ссылок на проекты TypeScript
- Рабочие пространства pnpm с TypeScript
- Стратегия общего пакета типов
- Инкрементальные сборки и кэш в монорепозиториях