Валидация ограниченных наборов значений в Superstruct строится вокруг
структуры enums, предназначенной для строгого контроля
допустимых литеральных значений. Такой подход используется, когда поле
может принимать только заранее определённый набор строк или чисел,
исключая любые отклонения от заданного списка.
В Superstruct перечисление создаётся через функцию
enums, которой передаётся массив допустимых значений:
import { enums } from 'superstruct'
const Status = enums(['idle', 'loading', 'success', 'error'])
Полученная структура проверяет, что значение строго совпадает с одним из элементов списка.
Примеры допустимых значений:
Status('idle') // корректно
Status('success') // корректно
Примеры ошибок:
Status('pending') // ошибка валидации
Status('') // ошибка валидации
Перечисления в Superstruct работают по принципу строгого равенства. Проверка не выполняет приведение типов и не нормализует входные данные.
Особенности:
===)Наиболее распространённый вариант использования — строковые enum-структуры:
const Role = enums(['admin', 'editor', 'viewer'])
Использование в объектах:
import { object, enums, string } from 'superstruct'
const User = object({
name: string(),
role: enums(['admin', 'editor', 'viewer'])
})
Валидация:
User({
name: 'Alex',
role: 'admin'
})
Допускается использование чисел в качестве допустимых значений:
const HttpStatus = enums([200, 400, 401, 404, 500])
Проверка:
HttpStatus(200) // корректно
HttpStatus(403) // ошибка
Числовые enum-структуры полезны при моделировании кодов состояния, фиксированных индексов или режимов работы.
Superstruct допускает смешанные наборы, содержащие строки и числа одновременно:
const Mixed = enums(['low', 1, 'high', 2])
Проверка строго сопоставляет тип и значение, поэтому '1'
и 1 рассматриваются как разные элементы.
При использовании TypeScript структура enums
автоматически выводит объединённый тип:
import { enums } from 'superstruct'
const Direction = enums(['left', 'right', 'up', 'down'])
// тип:
// 'left' | 'right' | 'up' | 'down'
Это позволяет синхронизировать runtime-валидацию и compile-time типизацию без дополнительных объявлений.
При передаче значения вне допустимого списка формируется ошибка валидации, содержащая информацию о допустимых вариантах.
Пример:
Direction('forward')
Результат ошибки включает:
Перечисления часто используются внутри сложных схем:
import { object, string, enums, number } from 'superstruct'
const Task = object({
id: number(),
title: string(),
status: enums(['todo', 'in_progress', 'done']),
priority: enums([1, 2, 3])
})
Такая комбинация позволяет описывать компактные модели данных с жёстко ограниченными состояниями.
При вложенности enum остаётся неизменным валидатором и применяется локально:
const Config = object({
theme: object({
mode: enums(['dark', 'light'])
})
})
Ошибка будет указывать на конкретное поле
theme.mode.
Перечисления можно рассматривать как специализированный случай
объединения литералов. Однако enums имеет более лаконичный
синтаксис и оптимизирован для фиксированных наборов.
Эквивалент через union:
import { union, literal } from 'superstruct'
const Status = union([
literal('idle'),
literal('loading'),
literal('success')
])
Но enums предоставляет более компактную форму:
const Status = enums(['idle', 'loading', 'success'])
Значения не приводятся автоматически к ожидаемому типу. Например:
const Flag = enums([1, 2, 3])
Flag('1') // ошибка
Даже при визуальной эквивалентности типов строка и число считаются различными значениями.
Перечисления часто применяются при проверке входящих данных API, где необходимо ограничить набор допустимых значений параметров:
const Query = object({
sort: enums(['asc', 'desc']),
page: number()
})
Такая модель исключает некорректные значения сортировки на уровне схемы.
Массив значений должен содержать уникальные элементы. Дублирование приводит к логической неоднозначности и может нарушать ожидаемое поведение валидации:
enums(['a', 'b', 'a']) // некорректная конфигурация
Перечисления оптимизированы под быстрый поиск через прямое сравнение. Проверка выполняется за линейное время относительно количества элементов, однако при небольших наборах (обычный кейс) это не оказывает заметного влияния на производительность.
Enum-структуры часто комбинируются с optional,
defaulted, nullable:
import { optional, enums } from 'superstruct'
const Mode = optional(enums(['auto', 'manual']))
Это позволяет расширять поведение схем без изменения базового набора допустимых значений.
'1' вместо
1)Enum не изменяет данные и не выполняет трансформации. Он работает исключительно как слой проверки. Входное значение возвращается без модификации при успешной валидации:
const value = Status('idle') // возвращает 'idle'