Ключевое слово enum в JSON Schema определяет
фиксированный набор допустимых значений для данных. В контексте Ajv
(Another JSON Schema Validator) перечисления компилируются в
высокоэффективные проверки, что делает их одним из самых быстрых
способов валидации ограниченных доменных значений.
enumПеречисление задаёт список допустимых литералов. Значение считается валидным, если оно строго совпадает с одним из элементов массива.
{
"type": "string",
"enum": ["pending", "active", "disabled"]
}
В Ajv проверка выполняется через строгие сравнения (===
для примитивов), поэтому тип имеет принципиальное значение. Значение
"1" и 1 считаются различными.
Наиболее распространённый вариант — строковые enum. Они часто используются для статусов, ролей, типов сущностей.
const schema = {
type: "object",
properties: {
status: {
type: "string",
enum: ["draft", "published", "archived"]
}
},
required: ["status"]
};
Особенность Ajv заключается в том, что такой enum компилируется в набор быстрых сравнений, оптимизированных под V8.
Числовые enum используются для фиксированных кодов или классификаторов.
const schema = {
type: "object",
properties: {
level: {
type: "number",
enum: [10, 20, 30]
}
}
};
Важно учитывать, что 10 и "10" не равны,
даже если включена частичная коэрсия типов.
JSON Schema допускает смешанные типы внутри enum, но в
практике Ajv это требует осторожности из-за строгого сравнения
типов.
const schema = {
enum: ["1", 1, true, null]
};
Такие конструкции усложняют поддержку и обычно заменяются более
строгими схемами с oneOf.
enum и constconst представляет частный случай enum с
единственным допустимым значением.
{ "const": "active" }
Эквивалент:
{ "enum": ["active"] }
В Ajv const компилируется в максимально упрощённую
проверку, что делает его предпочтительным для одиночных значений.
Enum часто применяется внутри свойств объектов для ограничения полей.
const schema = {
type: "object",
properties: {
role: {
type: "string",
enum: ["user", "admin", "moderator"]
},
priority: {
type: "integer",
enum: [0, 1, 2]
}
},
required: ["role"]
};
Такая структура позволяет фиксировать бизнес-правила на уровне схемы данных.
Enum может применяться к элементам массива через
items.
const schema = {
type: "array",
items: {
type: "string",
enum: ["red", "green", "blue"]
}
};
Каждый элемент массива проверяется независимо.
При вложенных структурах enum может использоваться на любом уровне вложенности:
const schema = {
type: "object",
properties: {
config: {
type: "object",
properties: {
mode: {
type: "string",
enum: ["auto", "manual"]
}
}
}
}
};
Ajv рекурсивно компилирует такие схемы в оптимизированные валидаторы.
При несоответствии значению из списка Ajv формирует ошибку с указанием допустимых значений.
Типичный формат ошибки:
should be equal to one of the allowed valuesСписок допустимых значений может быть включён в расширенный вывод
ошибок при использовании allErrors и verbose
режимов.
enum является одной из наиболее оптимизированных
конструкций Ajv:
Для небольших списков (<20 элементов) производительность близка к константной.
В строгом режиме Ajv может предупреждать о потенциальных проблемах схем:
enumtype и элементов enumconst ajv = new Ajv({ strict: true });
Дубликаты внутри enum не запрещены стандартом, но
считаются логической ошибкой.
При включённой опции coerceTypes Ajv может приводить
входные данные к типу схемы, однако enum остаётся
чувствительным к итоговому значению.
const ajv = new Ajv({ coerceTypes: true });
Например:
"1"enum: [1]Результат зависит от порядка коэрсии: если строка будет преобразована в число, проверка пройдёт, иначе нет.
Ajv поддерживает динамические перечисления через $data,
позволяя использовать значения из других частей данных.
const schema = {
type: "object",
properties: {
allowed: { type: "array", items: { type: "string" } },
value: {
type: "string",
enum: { $data: "1/allowed" }
}
}
};
В этом случае список допустимых значений берётся из поля
allowed текущего объекта.
В более сложных схемах enum заменяется или комбинируется
с oneOf, когда каждому значению соответствует своя
структура.
const schema = {
oneOf: [
{
properties: { type: { const: "A" }, data: { type: "string" } }
},
{
properties: { type: { const: "B" }, data: { type: "number" } }
}
]
};
Такой подход предпочтителен, когда значения перечисления определяют разные типы данных.
Для строковых значений часто возникает выбор между enum
и pattern:
enum — фиксированный набор значенийpattern — правило формирования строки// enum
{ enum: ["red", "green", "blue"] }
// pattern
{ type: "string", pattern: "^(red|green|blue)$" }
enum предпочтительнее из-за точности и
производительности.
Пустой массив в enum делает схему невыполнимой:
{ enum: [] }
Любое значение будет считаться невалидным, что используется для блокировки полей или состояний.
oneOfПеречисления формируют слой строгих доменных ограничений на уровне данных. В Ajv они выступают как один из базовых механизмов, позволяющих: