Диапазоны значений: min, max, positive, negative

Числовые ограничения в Zod используются для валидации диапазонов значений и позволяют задавать строгие условия на допустимые числа в схемах. Эти ограничения применяются к типу number и обеспечивают контроль границ, знака числа и допустимых интервалов.

Методы min() и max() задают нижнюю и верхнюю границы допустимого числового диапазона.

min — минимальное значение

Метод min() определяет наименьшее допустимое значение.

import { z } from "zod";

const schema = z.number().min(10);

schema.parse(15); // корректно
schema.parse(10); // корректно
schema.parse(5);  // ошибка

Логика проверки:

  • значение должно быть больше или равно указанного порога
  • по умолчанию граница включается (inclusive)

Второй параметр позволяет изменить сообщение об ошибке:

z.number().min(10, "Минимум 10")

max — максимальное значение

Метод max() задаёт верхнюю границу допустимого диапазона.

const schema = z.number().max(100);

schema.parse(50);  // корректно
schema.parse(100); // корректно
schema.parse(150); // ошибка

Условие:

  • значение должно быть меньше или равно заданного предела

Комбинация min и max формирует закрытый интервал:

const schema = z.number().min(10).max(100);

schema.parse(50);  // корректно
schema.parse(10);  // корректно
schema.parse(100); // корректно
schema.parse(9);   // ошибка
schema.parse(101); // ошибка

Такой подход эквивалентен проверке диапазона [10, 100].


Исключительные границы: open intervals

Zod поддерживает построение строгих интервалов через комбинацию min и max, но без встроенного параметра “exclusive” для чисел (в отличие от некоторых других библиотек). Эксклюзивные границы реализуются через смещение значений:

const schema = z.number().min(11).max(99);

Это фактически интервал (10, 100).


positive: положительные числа

Метод positive() ограничивает значения только положительными числами (строго больше нуля).

const schema = z.number().positive();

schema.parse(1);   // корректно
schema.parse(100); // корректно
schema.parse(0);   // ошибка
schema.parse(-5);  // ошибка

Особенности:

  • 0 не считается положительным
  • эквивалентно min(0, { exclusive: true }) в логическом смысле

Сценарии применения:

  • цены без нуля
  • коэффициенты
  • количественные метрики, исключающие отсутствие значения

Можно комбинировать с другими ограничениями:

const schema = z.number().positive().max(1000);

negative: отрицательные числа

Метод negative() ограничивает значения строго отрицательными числами (меньше нуля).

const schema = z.number().negative();

schema.parse(-1);   // корректно
schema.parse(-100); // корректно
schema.parse(0);    // ошибка
schema.parse(5);    // ошибка

Особенности:

  • ноль исключён
  • верхняя граница всегда строго ниже нуля

Пример комбинирования:

const schema = z.number().negative().min(-100);

Это задаёт диапазон [-100, 0).


Взаимодействие min/max с positive и negative

Методы positive() и negative() фактически задают базовое ограничение знака числа, а min() и max() уточняют диапазон.

positive + max

const schema = z.number().positive().max(10);

schema.parse(5);   // корректно
schema.parse(10);  // корректно
schema.parse(0);   // ошибка
schema.parse(11);  // ошибка

Диапазон: (0, 10]


negative + min

const schema = z.number().negative().min(-10);

schema.parse(-5);  // корректно
schema.parse(-10); // корректно
schema.parse(0);   // ошибка
schema.parse(-11); // ошибка

Диапазон: [-10, 0)


Граничные значения и поведение NaN

Zod строго валидирует числа, и значения вроде NaN не проходят проверку ни при каких диапазонах:

z.number().min(0).parse(NaN); // ошибка

Также не допускаются:

  • Infinity
  • -Infinity

Это важно, поскольку диапазонные методы предполагают конечные числовые значения.


Применение диапазонов в реальных схемах

Возраст пользователя

const ageSchema = z.number().min(0).max(120);

Логика:

  • исключает отрицательные значения
  • ограничивает реалистичным максимумом

Процентные значения

const percentSchema = z.number().min(0).max(100);

Часто используется в:

  • аналитике
  • UI прогресс-барах
  • финансовых моделях

Баланс или стоимость

const priceSchema = z.number().positive();

Или с ограничением:

const priceSchema = z.number().positive().max(1_000_000);

Температура

const temperatureSchema = z.number().min(-100).max(100);

Подходит для ограниченных физических диапазонов.


Поведение при приведении типов

Zod по умолчанию не приводит строки к числам, если не использовать z.coerce.number():

z.number().min(10).parse("15"); // ошибка

С коэрсией:

z.coerce.number().min(10).parse("15"); // корректно

Диапазонные ограничения применяются уже после преобразования типа.


Комбинирование с другими проверками

Диапазоны часто используются вместе с дополнительными ограничениями:

Целые числа

const schema = z.number().int().min(1).max(10);

Чётные числа (через refine)

const schema = z.number().min(1).max(100).refine((n) => n % 2 === 0);

Ограничение шага значений

const schema = z.number().min(0).max(1).refine((n) => n % 0.1 === 0);

Поведение ошибок

Каждое ограничение генерирует структурированную ошибку с кодом:

  • too_small — значение ниже минимума
  • too_big — значение выше максимума

Пример:

z.number().min(10).parse(5);

Результат ошибки содержит:

  • тип нарушения (too_small)
  • ожидаемое значение (minimum: 10)
  • фактическое значение

Особенности композиции диапазонов

При множественных ограничениях Zod не пересчитывает диапазон, а последовательно применяет проверки:

z.number()
  .min(0)
  .positive()
  .max(10);

Фактически:

  • positive() уже исключает 0
  • min(0) становится избыточным
  • итоговый эффективный диапазон: (0, 10]

Типовые ошибки при использовании диапазонов

Конфликт min и max

z.number().min(10).max(5);

Такая схема формально валидна при объявлении, но никогда не пропустит значение.


Избыточные ограничения

z.number().positive().min(1);

positive() уже подразумевает > 0, поэтому min(1) дополнительно сужает диапазон.


Использование без учёта типа данных

z.number().min(10).parse("20");

Ошибка возникает из-за отсутствия коэрсии.


Диапазонные методы в Zod формируют основу строгой числовой валидации, позволяя точно описывать допустимые границы, знаковые ограничения и комбинировать их с дополнительными правилами проверки без необходимости ручной реализации условной логики.