Ключевое слово not используется для инверсии схемы.
Валидация считается успешной только в том случае, если вложенная схема
возвращает ошибку.
Фактически not реализует логическое отрицание:
НЕ соответствует указанной схеме
Базовый синтаксис:
{
not: {
// схема
}
}
Если данные подходят под вложенную схему — проверка проваливается.
Запрет конкретного значения:
const schema = {
not: {
const: 10
}
}
Проверка:
validate(5) // true
validate(10) // false
Логика:
5 не равно 10 → проверка успешна10 соответствует const: 10 →
not инвертирует результат → ошибкаnotconst schema = {
not: {
type: "string"
}
}
Результаты:
validate(100) // true
validate(false) // true
validate("text") // false
const schema = {
not: {
type: "number"
}
}
const schema = {
not: {
type: "number",
maximum: -1
}
}
Проверка:
validate(10) // true
validate(0) // true
validate(-5) // false
requiredИногда требуется запретить определённое поле.
const schema = {
type: "object",
not: {
required: ["password"]
}
}
Проверка:
validate({
name: "Alex"
})
// true
validate({
name: "Alex",
password: "123"
})
// false
Как работает схема:
password отсутствует — вложенная схема не
проходитnot инвертирует результатconst schema = {
type: "object",
not: {
required: ["isAdmin", "role"]
}
}
Ошибка возникнет только при наличии одновременно:
{
isAdmin: true,
role: "admin"
}
not и enumconst schema = {
type: "string",
not: {
enum: ["admin", "root", "superuser"]
}
}
Проверка:
validate("user") // true
validate("admin") // false
validate("superuser") // false
const schema = {
type: "string",
not: {
const: ""
}
}
const schema = {
type: "string",
not: {
pattern: "^test"
}
}
Ошибка:
"test123"
Успешно:
"prod123"
const schema = {
type: "string",
format: "email",
not: {
pattern: "@gmail\\.com$"
}
}
const schema = {
type: "array",
not: {
maxItems: 0
}
}
const schema = {
type: "array",
not: {
minItems: 3,
maxItems: 3
}
}
Массив из трёх элементов станет недопустимым.
const schema = {
type: "object",
not: {
properties: {
type: {
const: "guest"
},
permissions: {
type: "array"
}
},
required: ["type", "permissions"]
}
}
Ошибка:
{
type: "guest",
permissions: ["write"]
}
allOfconst schema = {
allOf: [
{
type: "number"
},
{
not: {
multipleOf: 2
}
}
]
}
Допустимы только нечётные числа.
Проверка:
validate(3) // true
validate(4) // false
anyOfconst schema = {
anyOf: [
{
type: "string"
},
{
type: "number"
}
],
not: {
const: 0
}
}
Разрешены строки и числа, кроме 0.
oneOfconst schema = {
oneOf: [
{
type: "string"
},
{
type: "number"
}
],
not: {
type: "boolean"
}
}
not может содержать полноценную вложенную схему любой
сложности.
const schema = {
not: {
type: "object",
properties: {
role: {
const: "admin"
},
active: {
const: false
}
},
required: ["role", "active"]
}
}
Ошибка:
{
role: "admin",
active: false
}
if/then/elseconst schema = {
if: {
properties: {
age: {
minimum: 18
}
}
},
then: {
not: {
required: ["parentPermission"]
}
}
}
Логика:
parentPermission запрещеноconst schema = {
type: "object",
properties: {
login: {
type: "string"
},
password: {
type: "string"
},
role: {
type: "string"
}
},
required: ["login", "password"],
not: {
properties: {
login: {
const: "root"
},
role: {
const: "guest"
}
},
required: ["login", "role"]
}
}
Недопустимо:
{
login: "root",
password: "123",
role: "guest"
}
npm install ajv
const Ajv = require("ajv")
const ajv = new Ajv()
const schema = {
not: {
type: "null"
}
}
const validate = ajv.compile(schema)
console.log(validate(null))
console.log(validate(123))
Результат:
false
true
Пример:
const schema = {
not: {
const: 5
}
}
Ошибка:
[
{
instancePath: "",
schemaPath: "#/not",
keyword: "not",
params: {},
message: "must NOT be valid"
}
]
Главное сообщение:
must NOT be valid
notВажно понимать принцип работы.
Пример:
{
not: {
type: "object",
required: ["name"]
}
}
Данные:
5
Почему проверка успешна:
5 не является объектомnot инвертирует результатНеверная схема:
{
not: {
required: ["name"]
}
}
Проблема:
required применяется только к объектамПравильнее:
{
not: {
type: "object",
required: ["name"]
}
}
anyOfconst schema = {
not: {
anyOf: [
{
type: "string"
},
{
type: "number"
}
]
}
}
Допустимы любые значения, кроме строк и чисел.
allOfconst schema = {
not: {
allOf: [
{
type: "number"
},
{
minimum: 0
}
]
}
}
Запрещены положительные числа и ноль.
Иногда встречается двойная инверсия:
{
not: {
not: {
type: "string"
}
}
}
Это эквивалентно:
{
type: "string"
}
Подобные конструкции обычно ухудшают читаемость схемы.
not требует выполнения вложенной схемы полностью.
Сложные конструкции:
{
not: {
anyOf: [
...
]
}
}
или:
{
not: {
allOf: [
...
]
}
}
могут увеличивать стоимость валидации, особенно при глубокой вложенности и больших объектах.
not особенно
полезен{
not: {
const: "deprecated"
}
}
{
not: {
required: ["ssl", "insecureMode"]
}
}
{
not: {
properties: {
role: {
const: "guest"
},
accessLevel: {
const: "full"
}
},
required: ["role", "accessLevel"]
}
}
| Ключевое слово | Назначение |
|---|---|
allOf |
Все схемы должны пройти |
anyOf |
Достаточно одной схемы |
oneOf |
Должна пройти только одна |
not |
Схема не должна проходить |
typeПочти всегда полезно явно указывать тип:
{
not: {
type: "object",
required: ["token"]
}
}
Плохо читается:
{
not: {
anyOf: [
{
allOf: [
...
]
}
]
}
}
Хорошая схема легко читается как правило:
not: {
const: "admin"
}
или:
not: {
required: ["password"]
}
not| Вложенная схема | Результат not |
|---|---|
| Валидна | Ошибка |
| Невалидна | Успех |
| Задача | Решение |
|---|---|
| Запрет значения | not + const |
| Исключение списка | not + enum |
| Запрет типа | not + type |
| Исключение структуры | not + properties |
| Запрет поля | not + required |
| Исключение шаблона | not + pattern |
| Запрет диапазона | not + minimum/maximum |