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

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

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

Начать курс

Введение: что такое Valibot и зачем он нужен?

Valibot — это современная, модульная и лёгкая библиотека для валидации данных на языке TypeScript и JavaScript. В отличие от таких гигантов, как Zod или Joi, Valibot спроектирован с акцентом на минимальный размер бандла и tree-shaking (возможность удаления неиспользуемого кода).

Основная философия Valibot — «плати только за то, что используешь». Если вам нужно проверить только строку на минимальную длину, вы импортируете только string и minLength, а не всю библиотеку целиком. Это делает Valibot идеальным выбором для проектов, где важен размер итогового JavaScript-бандла (например, для мобильных приложений или библиотек компонентов).

Библиотека полностью типизирована и предоставляет отличную интеграцию с TypeScript, автоматически выводя типы из схем валидации. Valibot поддерживает как простые примитивы (строки, числа, булевы значения), так и сложные структуры (объекты, массивы, union-типы, рекурсивные схемы).

Установка

Valibot распространяется через пакетный менеджер npm. Для установки выполните следующую команду в терминале вашего проекта:

npm install valibot

Если вы используете yarn:

yarn add valibot

Для pnpm:

pnpm add valibot

После установки вы можете импортировать необходимые функции в ваш TypeScript-файл:

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

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

Давайте создадим простую схему валидации для формы регистрации пользователя. Мы проверим имя, email и возраст.

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

// 1. Определяем схему
const UserSchema = object({
  name: string([minLength(2, 'Имя должно содержать минимум 2 символа')]),
  email: string([email('Некорректный email')]),
  age: number([maxValue(120, 'Возраст не может быть больше 120')])
});

// 2. Данные для проверки
const inputData = {
  name: 'Анна',
  email: 'anna@example.com',
  age: 30
};

// 3. Валидируем
const result = safeParse(UserSchema, inputData);

if (result.success) {
  console.log('Данные валидны:', result.output);
  // result.output имеет тип { name: string; email: string; age: number; }
} else {
  console.error('Ошибки валидации:', result.issues);
  // result.issues — массив объектов с описанием ошибок
}

В этом примере мы использовали safeParse — безопасный метод, который не выбрасывает исключение, а возвращает объект с полем success. Если валидация прошла успешно, в result.output будут лежать проверенные данные с корректными типами.

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

Valibot предоставляет множество функций для создания схем. Рассмотрим самые важные из них.

1. string()

Что делает: Создаёт схему для валидации строковых значений. Принимает необязательный массив валидаторов для дополнительных проверок (длина, паттерн и т.д.).

Параметры:

  • validations (необязательно): массив функций-валидаторов, таких как minLength, maxLength, email, url, regex и других.

Пример:

import { string, minLength, maxLength, email } from 'valibot';

const UsernameSchema = string([minLength(3), maxLength(20)]);
const EmailSchema = string([email()]);

console.log(safeParse(UsernameSchema, 'Jo')); // { success: false, issues: [...] }
console.log(safeParse(EmailSchema, 'test@test.com')); // { success: true, output: 'test@test.com' }

2. number()

Что делает: Создаёт схему для валидации числовых значений. Поддерживает целые числа и числа с плавающей точкой.

Параметры:

  • validations (необязательно): массив валидаторов, таких как minValue, maxValue, integer, positive и других.

Пример:

import { number, minValue, maxValue, integer } from 'valibot';

const AgeSchema = number([integer(), minValue(0), maxValue(150)]);
const PriceSchema = number([minValue(0.01)]);

console.log(safeParse(AgeSchema, 25.5)); // { success: false } — не целое
console.log(safeParse(PriceSchema, 100)); // { success: true, output: 100 }

3. boolean()

Что делает: Создаёт схему для валидации булевых значений (true или false).

Параметры: Нет.

Пример:

import { boolean } from 'valibot';

const IsActiveSchema = boolean();

console.log(safeParse(IsActiveSchema, true)); // { success: true, output: true }
console.log(safeParse(IsActiveSchema, 'true')); // { success: false }

4. object()

Что делает: Создаёт схему для валидации объектов. Принимает объект, где ключи — это названия полей, а значения — схемы для этих полей.

Параметры:

  • entries: объект, определяющий структуру и типы полей.
  • validations (необязательно): массив валидаторов для всего объекта (например, для проверки зависимостей между полями).

Пример:

import { object, string, number } from 'valibot';

const ProductSchema = object({
  title: string(),
  price: number()
});

const result = safeParse(ProductSchema, { title: 'Книга', price: 500 });
console.log(result.success); // true

5. array()

Что делает: Создаёт схему для валидации массивов. Принимает схему для элемента массива.

Параметры:

  • item: схема для каждого элемента массива.
  • validations (необязательно): массив валидаторов для всего массива, например minLength, maxLength.

Пример:

import { array, string, minLength } from 'valibot';

const TagsSchema = array(string(), [minLength(1, 'Должен быть хотя бы один тег')]);

console.log(safeParse(TagsSchema, ['typescript', 'valibot'])); // { success: true }
console.log(safeParse(TagsSchema, [])); // { success: false }

6. union()

Что делает: Создаёт схему, которая принимает значение, соответствующее одной из переданных схем (логическое ИЛИ). Полезно для полей, которые могут быть разных типов.

Параметры:

  • options: массив схем, из которых нужно выбрать.

Пример:

import { union, string, number } from 'valibot';

const IdSchema = union([string(), number()]);

console.log(safeParse(IdSchema, 'abc123')); // { success: true, output: 'abc123' }
console.log(safeParse(IdSchema, 42));       // { success: true, output: 42 }
console.log(safeParse(IdSchema, true));     // { success: false }

7. optional()

Что делает: Делает схему опциональной. Если значение undefined или null, валидация проходит успешно, и возвращается undefined (или можно указать значение по умолчанию).

Параметры:

  • schema: схема, которую нужно сделать опциональной.
  • defaultValue (необязательно): значение, которое будет использовано, если входное значение отсутствует.

Пример:

import { object, string, optional } from 'valibot';

const UserSchema = object({
  name: string(),
  nickname: optional(string(), 'Аноним')
});

const result1 = safeParse(UserSchema, { name: 'Иван' });
console.log(result1.output); // { name: 'Иван', nickname: 'Аноним' }

const result2 = safeParse(UserSchema, { name: 'Иван', nickname: 'Вано' });
console.log(result2.output); // { name: 'Иван', nickname: 'Вано' }

8. nullable()

Что делает: Позволяет значению быть null в дополнение к основному типу. Отличается от optional тем, что nullable разрешает null, но не undefined.

Параметры:

  • schema: схема, которую нужно расширить для поддержки null.

Пример:

import { string, nullable } from 'valibot';

const NicknameSchema = nullable(string());

console.log(safeParse(NicknameSchema, 'Петя')); // { success: true, output: 'Петя' }
console.log(safeParse(NicknameSchema, null));   // { success: true, output: null }
console.log(safeParse(NicknameSchema, undefined)); // { success: false }

9. pipe()

Что делает: Позволяет объединить несколько схем в одну, применяя их последовательно. Это мощный инструмент для трансформации данных (например, преобразование строки в число после валидации).

Параметры:

  • schemas: массив схем, которые будут применяться по порядку. Результат выполнения предыдущей схемы передаётся в следующую.

Пример:

import { pipe, string, transform, minLength } from 'valibot';

// Схема, которая принимает строку, проверяет длину и преобразует в число
const StringToNumberSchema = pipe(
  string([minLength(1)]),
  transform((input) => Number(input))
);

const result = safeParse(StringToNumberSchema, '123');
console.log(result); // { success: true, output: 123 (number) }

const result2 = safeParse(StringToNumberSchema, '');
console.log(result2.success); // false

10. safeParse()

Что делает: Основная функция для выполнения валидации. Возвращает объект результата, который содержит поле success (boolean) и либо output (валидные данные), либо issues (массив ошибок).

Параметры:

  • schema: схема для валидации.
  • input: данные для проверки.

Пример:

import { string, safeParse } from 'valibot';

const result = safeParse(string(), 123);
if (!result.success) {
  console.log(result.issues[0].message); // "Invalid type: Expected string but received number"
}

Реальный практический пример использования

Рассмотрим сценарий: мы разрабатываем API для интернет-магазина. Нам нужно валидировать входящие данные для создания нового заказа. Заказ содержит обязательные поля (товары, адрес доставки) и опциональные (промокод, комментарий).

import {
  object, string, number, array, optional, email,
  minLength, maxLength, min                    

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