Библиотека Superstruct предоставляет встроенные механизмы для проверки числовых диапазонов. Наиболее распространённые сценарии:
Для этих задач используются функции min() и
max() из модуля superstruct.
import { number, min, max } from 'superstruct'
Базовый тип:
const Age = number()
Без дополнительных ограничений структура принимает любое число:
42
-10
3.14
0
Функция min() задаёт нижнюю границу допустимого
значения.
min(struct, threshold)
Где:
struct — исходная структура;threshold — минимально допустимое число.import { assert, number, min } from 'superstruct'
const Age = min(number(), 18)
assert(21, Age)
Проверка проходит успешно.
assert(15, Age)
Ошибка:
StructError: Expected a number greater than or equal to 18 but received `15`
import { object, string, number, min } from 'superstruct'
const User = object({
name: string(),
age: min(number(), 18),
})
Корректные данные:
{
name: 'Alex',
age: 25
}
Некорректные данные:
{
name: 'Tom',
age: 16
}
const Price = min(number(), 0)
Подходит для:
Примеры:
0
10
999
Недопустимо:
-5
const Temperature = min(number(), -50)
Теперь значения ниже -50 будут отклоняться.
Функция max() задаёт верхнюю границу допустимого
числа.
max(struct, threshold)
import { assert, number, max } from 'superstruct'
const Percent = max(number(), 100)
assert(80, Percent)
assert(150, Percent)
Ошибка:
StructError: Expected a number less than or equal to 100 but received `150`
const Rating = max(number(), 5)
Подходящие значения:
1
3
5
Недопустимо:
10
Обе функции можно объединять для задания диапазона.
import { number, min, max } from 'superstruct'
const Score = max(
min(number(), 0),
100
)
Допустимые значения:
0
50
100
Недопустимые:
-1
101
При большом количестве ограничений вложенность ухудшает читаемость.
Пример:
const Score = max(min(number(), 0), 100)
Часто используют промежуточные переменные:
const PositiveNumber = min(number(), 0)
const Score = max(PositiveNumber, 100)
const ProductPrice = max(
min(number(), 1),
100000
)
Такой подход предотвращает:
const Percentage = max(
min(number(), 0),
100
)
Примеры:
0
25
75
100
Ошибка:
-10
150
const Quantity = max(
min(number(), 1),
1000
)
Полезно для:
assert() выбрасывает исключение. Для более безопасной
проверки применяется validate().
import { validate, number, min } from 'superstruct'
const Age = min(number(), 18)
const [error, value] = validate(16, Age)
console.log(error)
Результат:
StructError: Expected a number greater than or equal to 18 but received `16`
const [error, value] = validate(25, Age)
console.log(error) // undefined
console.log(value) // 25
Чаще всего ограничения применяются внутри объектов.
import {
object,
string,
number,
min,
max
} from 'superstruct'
const Product = object({
title: string(),
price: max(
min(number(), 1),
100000
),
stock: max(
min(number(), 0),
5000
),
})
const RegisterForm = object({
age: min(number(), 18),
})
Некорректные данные:
{
age: 14
}
const Discount = max(
min(number(), 0),
90
)
Логика:
const CreditMonths = max(
min(number(), 1),
360
)
const Latitude = max(
min(number(), -90),
90
)
const Longitude = max(
min(number(), -180),
180
)
const FileSize = max(
min(number(), 1),
10 * 1024 * 1024
)
Пример ограничения файла до 10 МБ.
const Timeout = max(
min(number(), 100),
30000
)
Подход предотвращает:
const GameSettings = object({
graphics: object({
fps: max(
min(number(), 30),
240
),
}),
})
import {
optional,
number,
min
} from 'superstruct'
const Discount = optional(
min(number(), 0)
)
Допустимо:
undefined
10
25
Недопустимо:
-5
import {
defaulted,
number,
min
} from 'superstruct'
const Attempts = defaulted(
min(number(), 1),
3
)
Если значение отсутствует, используется 3.
min() включает границуmin(number(), 10)
Допустимо:
10
11
12
max() включает границуmax(number(), 100)
Допустимо:
100
99
50
min() и max() работают как с целыми, так и
с дробными значениями.
const Temperature = max(
min(number(), -10.5),
45.8
)
const Value = number()
Infinity технически является числом в JavaScript.
assert(Infinity, Value)
Проверка пройдёт успешно.
Для ограничения диапазона необходимо использовать
max().
const SafeValue = max(number(), 1000000)
assert(NaN, number())
NaN не проходит проверку number() в
Superstruct.
import {
object,
string,
number,
min,
max,
validate
} from 'superstruct'
const Employee = object({
name: string(),
age: max(
min(number(), 18),
65
),
salary: min(number(), 0),
})
const data = {
name: 'John',
age: 70,
salary: 5000,
}
const [error, value] = validate(data, Employee)
if (error) {
console.log(error.message)
}
Результат:
Expected a number less than or equal to 65 but received `70`
const Amount = min(number(), 0)
const Percent = max(
min(number(), 0),
100
)
const Age = max(
min(number(), 0),
120
)
const Rating = max(
min(number(), 1),
5
)
const FPS = max(
min(number(), 30),
240
)
Неверно:
min(18, number())
Правильно:
min(number(), 18)
Неверно:
min(18)
Правильно:
min(number(), 18)
Нежелательно:
validate(value, max(min(number(), 0), 100))
Лучше создавать структуру один раз:
const Score = max(
min(number(), 0),
100
)
validate(value, Score)
Структуры Superstruct рекомендуется переиспользовать.
Плохой вариант:
function validateAge(age) {
return validate(age, min(number(), 18))
}
Лучше:
const Age = min(number(), 18)
function validateAge(age) {
return validate(age, Age)
}
Это уменьшает количество создаваемых объектов и улучшает производительность при частых проверках.
min() и max() удобно комбинировать с
пользовательскими правилами.
import {
refine,
number,
min,
max
} from 'superstruct'
const EvenNumber = refine(
max(
min(number(), 0),
100
),
'EvenNumber',
value => value % 2 === 0
)
Допустимо:
2
20
100
Недопустимо:
3
101
-2