TypeScript-библиотеки 2024: гид по экосистеме для разработчика

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Почему TypeScript — это не просто мода, а необходимость

Когда в 2012 году Microsoft представила TypeScript, мало кто верил, что надстройка над JavaScript станет стандартом индустрии. Сегодня TypeScript — это не просто «ещё один язык», а полноценная экосистема, которая меняет подход к разработке. По данным State of JS 2023, более 70% опрошенных разработчиков используют TypeScript в своих проектах, и эта цифра продолжает расти.

Но дело не только в статической типизации. Настоящая магия TypeScript раскрывается через библиотеки, которые используют его возможности на 100%. Забудьте про скучные «обёртки» для JavaScript-пакетов — мы поговорим о настоящих TypeScript-native инструментах, которые заставят ваш код петь.

В этой статье мы разберём самые интересные и полезные библиотеки TypeScript, которые стоит добавить в свой арсенал в 2024 году. От валидации данных до работы с базами данных — приготовьтесь удивляться.

Zod: король валидации данных

Если вы когда-нибудь писали код для проверки входных данных вручную, вы знаете, как это утомительно. Zod решает эту проблему элегантно и типизированно.

Почему Zod, а не Joi или Yup?

Главное преимущество Zod — это TypeScript-first подход. Все схемы автоматически выводят типы, и вам не нужно дублировать типы вручную. Никакого typeof, никаких интерфейсов, которые нужно синхронизировать с валидаторами.

import { z } from 'zod';

// Создаём схему
const UserSchema = z.object({
  name: z.string().min(2, 'Имя должно быть длиннее 2 символов'),
  email: z.string().email('Некорректный email'),
  age: z.number().int().positive().optional(),
  role: z.enum(['admin', 'user', 'moderator']).default('user'),
});

// Автоматически получаем тип
type User = z.infer<typeof UserSchema>;
// { name: string; email: string; age?: number; role: "admin" | "user" | "moderator" }

// Валидация данных
const result = UserSchema.safeParse({
  name: 'Анна',
  email: 'anna@example.com',
  age: 25,
});

if (!result.success) {
  console.error(result.error.errors);
} else {
  // result.data — полностью типизированный объект
  console.log(result.data.name); // string
}

Zod также поддерживает сложные схемы: объединения (union), пересечения (intersection), рекурсивные типы и даже трансформации данных. Это идеальный выбор для API-валидации, форм и конфигураций.

Prisma: ORM, который чувствует TypeScript

Работа с базами данных на TypeScript долгое время была компромиссом. TypeORM был громоздким, Sequelize — медленным, а Knex — недостаточно типизированным. Prisma изменил правила игры.

Как работает Prisma?

Вместо того чтобы писать модели в коде, вы описываете схему данных в специальном файле schema.prisma. Prisma генерирует TypeScript-клиент с полной поддержкой типов.

// schema.prisma
model User {
  id        Int      @id @default(autoincrement())
  email     String   @unique
  name      String?
  posts     Post[]
  createdAt DateTime @default(now())
}

model Post {
  id        Int      @id @default(autoincrement())
  title     String
  content   String?
  published Boolean  @default(false)
  author    User     @relation(fields: [authorId], references: [id])
  authorId  Int
}

// Использование в коде
import { PrismaClient } from '@prisma/client';

const prisma = new PrismaClient();

// Полностью типизированные запросы
async function getUsersWithPosts() {
  const users = await prisma.user.findMany({
    include: {
      posts: {
        where: { published: true },
        select: { title: true, createdAt: true },
      },
    },
    orderBy: { createdAt: 'desc' },
  });

  // users — массив с правильными типами
  users.forEach(user => {
    console.log(user.email, user.posts.length);
  });
}

Prisma автоматически генерирует типы для всех моделей, включая вложенные запросы. Ошибки в названиях полей или типах данных отлавливаются на этапе компиляции, а не в рантайме. Это экономит часы отладки.

tRPC: API без REST и GraphQL

tRPC — это, пожалуй, самая инновационная библиотека в этом списке. Она позволяет создавать API между клиентом и сервером без написания REST-эндпоинтов или GraphQL-схем. Всё работает через обычные функции, но с полной типизацией.

Как это выглядит на практике?

// Серверная часть
import { initTRPC } from '@trpc/server';
import { z } from 'zod';

const t = initTRPC.create();

const appRouter = t.router({
  getUser: t.procedure
    .input(z.string()) // валидация через Zod
    .query(async (opts) => {
      const user = await db.user.findUnique({ where: { id: opts.input } });
      return user;
    }),
  createPost: t.procedure
    .input(z.object({
      title: z.string(),
      content: z.string().optional(),
    }))
    .mutation(async (opts) => {
      return await db.post.create({ data: opts.input });
    }),
});

export type AppRouter = typeof appRouter;

// Клиентская часть
import { createTRPCReact } from '@trpc/react-query';
import type { AppRouter } from './server';

const trpc = createTRPCReact<AppRouter>();

function UserProfile({ userId }: { userId: string }) {
  const { data, isLoading } = trpc.getUser.useQuery(userId);

  if (isLoading) return <div>Загрузка...</div>;

  // data — полностью типизированный объект User
  return <h1>{data.name}</h1>;
}

tRPC автоматически синхронизирует типы между сервером и клиентом. Если вы измените процедуру на сервере, TypeScript на клиенте сразу укажет на ошибки. Никаких ручных спецификаций, никакого дублирования типов.

Valibot: лёгкая альтернатива Zod

Если Zod кажется вам слишком тяжёлым (а он действительно добавляет ~10KB в бандл), обратите внимание на Valibot. Эта библиотека построена на модульной архитектуре: вы импортируете только те валидаторы, которые используете.

Сравнение Zod и Valibot

import { object, string, number, email, minLength, safeParse } from 'valibot';

const UserSchema = object({
  name: string([minLength(2, 'Имя слишком короткое')]),
  email: string([email('Некорректный email')]),
  age: number(),
});

type User = Output<typeof UserSchema>;

const result = safeParse(UserSchema, {
  name: 'Анна',
  email: 'anna@example.com',
  age: 25,
});

if (result.success) {
  console.log(result.output.name); // типизированный доступ
}

Valibot занимает всего 1KB в сжатом виде (против 10KB у Zod). Для проектов, где размер бандла критичен (например, мобильные приложения на React Native), это может быть решающим фактором.

Effect-TS: функциональное программирование на стероидах

Если вы знакомы с функциональными языками вроде Haskell или Scala, Effect-TS покажется вам родным

Блоги

Рекомендаций по книгам