Валидация числовых значений в схемах Yup опирается на цепочку
методов, которые уточняют допустимые свойства числа. При использовании
YupResolver эти правила становятся частью общей схемы
валидации, а результат автоматически интегрируется в механизмы обработки
форм, например в связке с React Hook Form.
Числовые ограничения positive, negative и
integer относятся к базовому набору предикатов,
определяющих допустимый диапазон и форму числа. Они применяются после
базового определения типа number() и могут комбинироваться
между собой и с другими правилами, такими как required,
min, max, typeError.
Любая числовая схема начинается с объявления типа:
import * as Yup from "yup";
const schema = Yup.object({
amount: Yup.number()
});
На этом этапе значение уже приводится к числу, но не ограничивается по знаку или форме. Любые дополнительные ограничения добавляются через цепочку методов.
Метод positive() ограничивает допустимые значения только
числами больше нуля. Ноль при этом считается недопустимым значением.
const schema = Yup.object({
price: Yup.number()
.positive("Значение должно быть больше нуля")
});
Поведение positive():
0.1, 1,
100, 3.140, -1,
-10Внутри YupResolver ошибка валидации передаётся в
структуру errors, где ключ соответствует имени поля, а
сообщение формируется из аргумента метода или стандартного сообщения
библиотеки.
Комбинация с обязательностью поля:
price: Yup.number()
.typeError("Введите число")
.positive("Только положительное значение")
.required("Поле обязательно")
Метод negative() ограничивает значения строго
отрицательными числами. Ноль не считается допустимым.
const schema = Yup.object({
debt: Yup.number()
.negative("Значение должно быть отрицательным")
});
Допустимые значения:
-1, -10, -0.5Недопустимые:
0, 1, 100Особенность применения в схемах через YupResolver
заключается в том, что ошибка формируется на уровне схемы и не требует
дополнительной логики в компоненте формы.
Комбинированный вариант:
debt: Yup.number()
.typeError("Введите число")
.negative("Должно быть отрицательное значение")
.required("Поле обязательно")
Метод integer() ограничивает значение только целыми
числами, исключая дробные значения. Это правило работает независимо от
знака числа.
const schema = Yup.object({
quantity: Yup.number()
.integer("Допустимы только целые числа")
});
Допустимые значения:
1, 10, -5,
0Недопустимые:
1.5, 0.1, -3.14При использовании с YupResolver дробное значение
автоматически преобразуется в ошибку валидации, даже если оно корректно
распознано как число на уровне JavaScript.
Методы могут комбинироваться для создания более строгих ограничений. При этом порядок вызова не влияет на результат, так как Yup строит цепочку проверок декларативно.
const schema = Yup.object({
count: Yup.number()
.positive("Только положительные значения")
.integer("Только целые числа")
});
Результат:
1, 2, 1000, 1.5, -1const schema = Yup.object({
loss: Yup.number()
.negative("Только отрицательные значения")
.integer("Только целые числа")
});
Результат:
-1, -10, -1000, 1, -1.2YupResolver выступает адаптером между схемой Yup и
системой валидации формы. При каждом изменении значения:
Пример интеграции:
import { useForm } from "react-hook-form";
import { yupResolver } from "@hookform/resolvers/yup";
const schema = Yup.object({
amount: Yup.number()
.positive()
.integer()
});
const { register, handleSubmit, formState: { errors } } = useForm({
resolver: yupResolver(schema)
});
Структура errors.amount.message будет содержать текст
ошибки первого нарушенного правила в цепочке валидации.
При работе с HTML-формами значения приходят как строки. Yup выполняет автоматическое преобразование, но поведение зависит от содержимого:
"10" → 10 (корректное число)"10.5" → 10.5 (валидное число для
number(), но может нарушить integer())"" → NaN (требует required
или typeError для обработки)Поэтому при использовании positive,
negative, integer часто добавляется явная
обработка ошибок типа:
Yup.number()
.typeError("Требуется числовое значение")
.positive()
.integer()
Если в схеме присутствует несколько ограничений, ошибка возвращается по первому нарушенному правилу, которое срабатывает в процессе проверки. Например:
Yup.number()
.positive("Положительное число")
.integer("Целое число")
Для значения -2.5 будет возвращена ошибка
positive, так как проверка знака выполняется раньше логики
проверки дробной части.
В более сложных объектах схемы числовые ограничения часто используются вместе с зависимыми правилами:
const schema = Yup.object({
minAge: Yup.number()
.positive()
.integer()
.min(18, "Минимальный возраст 18"),
maxAge: Yup.number()
.positive()
.integer()
.max(65, "Максимальный возраст 65")
});
В таких случаях YupResolver агрегирует ошибки по каждому
полю независимо, сохраняя изоляцию валидации.
Поведение методов positive, negative,
integer не включает автоматическую нормализацию данных. Они
только проверяют соответствие значения правилам. Любая трансформация
должна быть определена отдельно через transform():
Yup.number()
.transform((value, originalValue) => {
return String(originalValue).trim() === "" ? undefined : value;
})
.positive()
.integer()