Валидация данных в TypeScript: от теории к практике
Одна из ключевых проблем при разработке на TypeScript — разрыв между статической типизацией и реальными данными, которые приходят из внешних источников (API, формы, localStorage). TypeScript проверяет типы на этапе компиляции, но в рантайме типы исчезают. Валидация данных — это процесс проверки соответствия данных определённым правилам в рантайме, что критически важно для надёжности приложений.
В этой статье мы разберём популярные библиотеки для валидации данных в TypeScript: Zod, Yup, Joi и class-validator. Рассмотрим их особенности, примеры использования и поможем выбрать подходящий инструмент для вашего проекта.
Почему недостаточно только TypeScript?
TypeScript — это инструмент для разработчика. Он помогает писать более безопасный код, но не защищает от:
- Некорректных данных из API (поле
ageможет прийти как строка"25") - Отсутствия обязательных полей
- Неправильных форматов (email, URL, телефон)
- Выхода значений за допустимые диапазоны
Валидация данных в рантайме решает эти проблемы, проверяя данные на соответствие схеме и выдавая понятные ошибки.
Zod — современный стандарт
Zod — самая популярная библиотека для валидации в TypeScript. Её главное преимущество — тесная интеграция с системой типов: из схемы можно вывести тип автоматически.
Установка
npm install zod
Пример использования
import { z } from 'zod';
// Определяем схему
const UserSchema = z.object({
id: z.number().positive(),
email: z.string().email(),
age: z.number().min(18).max(120).optional(),
role: z.enum(['admin', 'user', 'guest']),
});
// Выводим тип из схемы
type User = z.infer<typeof UserSchema>;
// Валидация
const result = UserSchema.safeParse({
id: 1,
email: 'user@example.com',
age: 25,
role: 'admin',
});
if (result.success) {
// result.data — корректные данные с типом User
console.log(result.data.email);
} else {
// result.error — подробная информация об ошибках
console.log(result.error.format());
}
Ключевые возможности Zod:
- Автоматический вывод типов через
z.infer - Трансформация данных (например, приведение строк к числам)
- Валидация вложенных объектов и массивов
- Поддержка union, intersection, discriminated unions
- Refinement — кастомные проверки
Yup — проверенный временем
Yup — библиотека от авторов Formik. Идеально подходит для валидации форм в React. Yup имеет более декларативный синтаксис и богатую экосистему.
Пример
import * as yup from 'yup';
const schema = yup.object().shape({
name: yup.string().required('Имя обязательно'),
email: yup.string().email('Некорректный email').required(),
age: yup.number().positive().integer().min(18, 'Возраст должен быть не менее 18'),
tags: yup.array().of(yup.string()).min(1, 'Выберите хотя бы один тег'),
});
schema.validate({
name: 'Иван',
email: 'ivan@example.com',
age: 25,
tags: ['typescript'],
}).then(validData => {
console.log('Данные корректны:', validData);
}).catch(err => {
console.log('Ошибка:', err.errors);
});
Особенности Yup:
- Локализация сообщений об ошибках
- Валидация по требованию (lazy validation)
- Трансформация значений (cast)
- Интеграция с Formik из коробки
Joi — мощный и строгий
Joi — библиотека с огромным набором валидаторов. Изначально создавалась для Node.js (Hapi.js), но отлично работает и с TypeScript.
Пример
import Joi from 'joi';
const schema = Joi.object({
username: Joi.string().alphanum().min(3).max(30).required(),
password: Joi.string().pattern(new RegExp('^[a-zA-Z0-9]{3,30}$')),
email: Joi.string().email({ tlds: { allow: false } }),
birth_year: Joi.number().integer().min(1900).max(2024),
});
const { error, value } = schema.validate({
username: 'abc',
password: 'pass123', Также в библиотеке
Marten для C# (.NET): полное руководство с примерами
Мониторинг C++ приложений: библиотека metrics для сбора метрик
Логирование в Go (Golang): лучшие библиотеки и решения для продакшена
Валидация данных в C# (.NET): библиотеки и подходы