Что такое 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
Также в библиотеке
Отправка SMS на C++: API библиотека LibCurl и REST-запросы
WebSocket в C++: библиотеки и практическое применение
Redis клиент для TypeScript: ioredis и redis (node-redis)
Конфигурация приложений Swift: инструменты и библиотеки для iOS/macOS
CLI фреймворк для C++: cppcli — создание консольных приложений