typia для TypeScript: полное руководство с примерами

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

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

Начать курс

Что такое typia и зачем она нужна?

typia — это мощная библиотека для TypeScript, которая предоставляет runtime-проверку типов (runtime type validation) с уникальной особенностью: она генерирует код проверки на этапе компиляции (compile-time), а не во время выполнения. Это делает её одной из самых быстрых библиотек для валидации данных в экосистеме TypeScript.

Основные проблемы, которые решает typia:

  • Производительность: В отличие от популярных библиотек (zod, yup, io-ts), typia не использует рефлексию или декораторы. Вместо этого она генерирует оптимизированный код проверки на этапе сборки, что даёт прирост скорости в 10–100 раз.
  • Безопасность типов: Вы получаете гарантию, что данные, приходящие из внешних источников (API, базы данных, формы), соответствуют вашим TypeScript-интерфейсам.
  • Минимальный бойлерплейт: Вам не нужно писать отдельные схемы валидации — typia использует ваши существующие TypeScript-типы.
  • Поддержка сложных типов: Union, intersection, conditional types, mapped types — всё это работает "из коробки".

Библиотека особенно полезна для:

  • Backend-разработки на Node.js с TypeScript
  • Frontend-приложений, где требуется валидация форм или API-ответов
  • Микросервисной архитектуры, где важна скорость сериализации/десериализации
  • Проектов, где критична производительность и безопасность типов

Установка

Установка typia состоит из двух шагов: сама библиотека и TypeScript-трансформер (компилятор).

Шаг 1. Установка через npm

npm install typia
# или
yarn add typia
# или
pnpm add typia

Шаг 2. Установка трансформера

npm install --save-dev typia-transform
# или
yarn add -D typia-transform
# или
pnpm add -D typia-transform

Шаг 3. Настройка tsconfig.json

Добавьте плагин в ваш tsconfig.json:

{
  "compilerOptions": {
    "plugins": [
      {
        "transform": "typia-transform"
      }
    ]
  }
}

Шаг 4. Использование с ttypescript (рекомендуется)

Установите ttypescript для автоматической трансформации:

npm install --save-dev ttypescript

Затем замените tsc на ttsc в ваших скриптах package.json:

{
  "scripts": {
    "build": "ttsc",
    "start": "node dist/index.js"
  }
}

Важно: typia требует TypeScript версии 4.4 или выше. Без трансформера библиотека работать не будет.

Быстрый старт с примером кода

Давайте создадим простой пример валидации данных пользователя.

import typia from "typia";

// Определяем интерфейс
interface IUser {
  id: number;
  name: string;
  email: string;
  age: number;
  isActive: boolean;
}

// Создаём функцию валидации
const validateUser = typia.createValidate<IUser>();

// Тестовые данные
const testData = {
  id: 1,
  name: "Иван Петров",
  email: "ivan@example.com",
  age: 30,
  isActive: true,
};

// Валидация
const result = validateUser(testData);

if (result.success) {
  console.log("Данные валидны:", result.data);
} else {
  console.log("Ошибка валидации:", result.errors);
}

// Пример с некорректными данными
const badData = {
  id: "не число", // Должно быть number
  name: "Иван",
  email: "не email",
  age: -5,
  isActive: "yes", // Должно быть boolean
};

const badResult = validateUser(badData);
console.log("Ошибки:", badResult.errors);

Этот пример показывает, как легко можно валидировать данные, используя только TypeScript-интерфейс. Никаких дополнительных схем или декораторов!

Основные методы и функции

1. typia.createValidate<T>()

Что делает: Создаёт функцию-валидатор для типа T. Возвращает объект с полями success, data (если успешно) и errors (если ошибка).

Параметры: Нет параметров. Тип передаётся как generic.

Возвращает: Функцию (input: unknown) => IValidation<T>

import typia from "typia";

interface IPoint {
  x: number;
  y: number;
}

const validatePoint = typia.createValidate<IPoint>();

const valid = validatePoint({ x: 10, y: 20 });
console.log(valid.success); // true

const invalid = validatePoint({ x: "string", y: 20 });
console.log(invalid.success); // false
console.log(invalid.errors); // [{ path: "$.x", expected: "number", value: "string" }]

2. typia.createAssert<T>()

Что делает: Создаёт функцию-ассерт для типа T. В случае ошибки выбрасывает исключение TypeGuardError.

Параметры: Нет параметров. Тип передаётся как generic.

Возвращает: Функцию (input: unknown) => T

import typia from "typia";

interface IUser {
  id: number;
  name: string;
}

const assertUser = typia.createAssert<IUser>();

try {
  const user = assertUser({ id: 1, name: "Alice" });
  console.log("User is valid:", user);
} catch (error) {
  console.error("Validation failed:", error.message);
}

// Выбросит ошибку
try {
  assertUser({ id: "invalid", name: "Bob" });
} catch (error) {
  console.error(error); // TypeGuardError
}

3. typia.createIs<T>()

Что делает: Создаёт функцию-проверку (type guard). Возвращает true или false.

Параметры: Нет параметров. Тип передаётся как generic.

Возвращает: Функцию (input: unknown) => input is T

import typia from "typia";

interface ICar {
  brand: string;
  year: number;
}

const isCar = typia.createIs<ICar>();

const data1 = { brand: "Toyota", year: 2020 };
const data2 = { brand: "Tesla", year: "2023" };

console.log(isCar(data1)); // true
console.log(isCar(data2)); // false

// Использование в условном операторе
if (isCar(data1)) {
  console.log(data1.brand.toUpperCase()); // TypeScript знает, что data1 - это ICar
}

4. typia.createStringify<T>()

Что делает: Создаёт быструю функцию сериализации в JSON. Работает быстрее стандартного JSON.stringify за счёт генерации кода на этапе компиляции.

Параметры: Нет параметров. Тип передаётся как generic.

Возвращает: Функцию (input: T) => string

import typia from "typia";

interface IProduct {
  id: number;
  name: string;
  price: number;
  tags: string[];
}

const stringify = typia.createStringify<IProduct>();

const product: IProduct = {
  id: 101,
  name: "Ноутбук",
  price: 999.99,
  tags: ["электроника", "техника"],
};

const jsonString = stringify(product);
console.log(jsonString);
// {"id":101,"name":"Ноутбук","price":999.99,"tags":["электроника","техника"]}

5. typia.createRandom<T>()

Что делает: Генерирует случайные данные, соответствующие типу T. Полезно для тестирования и создания моков.

Параметры: Нет параметров. Тип передаётся как generic.

Возвращает: Функцию () => T

import typia from "typia";

interface IAddress {
  street: string;
  city: string;
  zipCode: string;
}

const generateAddress = typia.createRandom<IAddress>();

const randomAddress = generateAddress();
console.log(randomAddress);
// Пример: { street: "ул. Ленина, д. 42", city: "Москва", zipCode: "101000" }

// Каждый вызов генерирует новые данные
console.log(generateAddress());
console.log(generateAddress());

6. typia.createEquals<T>()

Что делает: Проверяет, что два объекта равны по структуре и значениям. Отличается от createIs тем, что проверяет точное соответствие (включая лишние свойства).

Параметры: Нет параметров. Тип передаётся как generic.

Возвращает: Функцию (input: unknown) => input is T

import typia from "typia";

interface IConfig {
  host: string;
  port: number;
}

const equalsConfig = typia.createEquals<IConfig>();

const config1 = { host: "localhost", port: 3000 };
const config2 = { host: "localhost", port: 3000, extra: true };

console.log(equalsConfig(config1)); // true
console.log(equalsConfig(config2)); // false (лишнее свойство 'extra')

7. typia.createAssertClone<T>()

Что делает: Комбинирует проверку типа и глубокое клонирование объекта. Возвращает новый объект, соответствующий типу T.

Параметры: Нет параметров. Тип передаётся как generic.

Возвращает: Функцию (input: unknown) => T

import typia from "typia";

interface IData {
  id: number;
  nested: {
    value: string;
  };
}

const assertClone = typia.createAssertClone<IData>();

const original = { id: 1, nested: { value: "test" } };
const cloned = assertClone(original);

console.log(cloned === original); // false (разные объекты)
console.log(cloned.nested === original.nested); // false (глубокое клонирование)

// При ошибке выбрасывает исключение
try {
  assertClone({ id: "bad", nested: { value: 123 } });
} catch (error) {
  console.error("Ошибка валидации и клонирования");
}

8. typia.createPrune<T>()

Что делает: Удаляет лишние свойства из объекта, оставляя только те, что определены в типе T. Полезно для очистки данных перед отправкой.

Параметры: Нет параметров. Тип передаётся как generic.

Возвращает: Функцию (input: T) => T

import typia from "typia";

interface IUserPublic {
  id: number;
  name: string;
}

const pruneUser = typia.createPrune<IUserPublic>();

const userData = {
  id: 1,
  name: "Alice",
  password: "secret123", // Лишнее свойство
  internalNote: "admin", // Лишнее свойство
};

const cleaned = pruneUser(userData);
console.log(cleaned);
// { id: 1, name: "Alice" } - лишние свойства удалены
console.log(userData === cleaned); // true (мутирует исходный объект)

9. typia.createClone<T>()

Что делает: Создаёт глубокую копию объекта без проверки типов. Быстрее, чем JSON.parse(JSON

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