Контекст валидации в Yup позволяет передавать внешние данные в момент выполнения проверки схемы и использовать их внутри правил валидации, кастомных тестов и условных схем. Этот механизм делает возможным создание динамических схем, поведение которых зависит не только от входного значения, но и от окружения, в котором выполняется проверка.
В Yup контекст передаётся через параметры метода валидации. Основной
способ — использование options.context при вызове
validate или validateSync.
Контекст становится доступным внутри схемы и всех её внутренних тестов.
import * as Yup fr om 'yup';
const schema = Yup.object({
email: Yup.string().required()
});
schema.validate(
{ email: 'test@example.com' },
{
context: {
role: 'admin'
}
}
);
Переданный объект не изменяет схему, но становится частью вычислительного окружения.
Внутри test функция Yup предоставляет доступ к контексту
через this.options.context.
const schema = Yup.string().test(
'check-role',
'Недостаточно прав',
function (value) {
const { role } = this.options.context || {};
if (role !== 'admin') {
return false;
}
return true;
}
);
Контекст в этом случае позволяет отделить бизнес-логику от схемы и управлять поведением извне.
Одним из ключевых применений контекста является условная валидация
через when. Хотя when чаще использует значения
полей, он также может опираться на внешний контекст через функцию.
const schema = Yup.object({
password: Yup.string().when([], {
is: () => true,
then: (s) => s.min(8),
})
});
Более гибкий вариант:
const schema = Yup.string().when('$minLength', (minLength, schema) => {
return schema.min(minLength || 0);
});
Здесь $minLength берётся из контекста, переданного при
валидации.
schema.validate('abc', {
context: {
minLength: 5
}
});
Символ $ является соглашением для обозначения
контекстных переменных в Yup.
Контекст доступен не только в корневой схеме, но и во всех вложенных структурах: объектах, массивах и вложенных полях.
const schema = Yup.object({
user: Yup.object({
name: Yup.string().when('$isLocked', (isLocked, schema) => {
return isLocked ? schema.required() : schema.notRequired();
})
})
});
schema.validate(
{ user: { name: '' } },
{ context: { isLocked: true } }
);
Контекст распространяется рекурсивно вниз по дереву схемы.
Более низкоуровневый доступ к контексту осуществляется через
mixed().test, который является базовым механизмом Yup.
const schema = Yup.mixed().test(
'feature-flag',
'Функция отключена',
function (value) {
const { featureEnabled } = this.options.context || {};
return featureEnabled === true;
}
);
Такой подход используется при реализации флагов функций и динамических ограничений.
Контекст может комбинироваться с ref, что позволяет
создавать гибридные правила, где часть данных берётся из формы, а часть
— извне.
const schema = Yup.object({
role: Yup.string(),
secret: Yup.string().when(['role', '$env'], (role, env, schema) => {
if (role === 'admin' && env === 'production') {
return schema.required();
}
return schema.notRequired();
})
});
Здесь одновременно используются данные объекта и внешнего окружения.
В lazy контекст особенно полезен, когда структура данных
зависит от внешних параметров.
const schema = Yup.lazy((value, options) => {
const { type } = options.context || {};
if (type === 'array') {
return Yup.array().of(Yup.string());
}
return Yup.object({
value: Yup.string()
});
});
Такой подход используется при динамической типизации входных данных.
Контекст позволяет учитывать параметры клиента или организации.
const schema = Yup.string().test(
'tenant-lim it',
'Превышен лимит',
function (value) {
const { maxLength } = this.options.context || {};
return !maxLength || value.length <= maxLength;
}
);
Yup.boolean().test(
'feature-toggle',
'Функция отключена',
function (value) {
return this.options.context?.features?.newUI === true;
}
);
Контекст может использоваться для динамической локализации ошибок.
const schema = Yup.string().required(function () {
const locale = this.options.context?.locale;
if (locale === 'ru') {
return 'Поле обязательно';
}
return 'Field is required';
});
Контекст в Yup имеет несколько характерных особенностей:
validate;Контекст делает схему более гибкой, но одновременно снижает её детерминированность. Одна и та же схема может вести себя по-разному в зависимости от переданных данных окружения.
Особенно важно учитывать:
undefined;По этой причине контекст обычно применяют для параметров окружения, флагов и конфигураций, но не для основной бизнес-валидации данных формы.