В библиотеке Superstruct валидация строк с использованием шаблонов строится вокруг механизма сопоставления значений с регулярными выражениями. Этот подход позволяет задавать строгие ограничения на формат данных, сохраняя при этом декларативный стиль описания структуры.
Строковые структуры в Superstruct базируются на базовом типе
string(), который проверяет, что значение действительно
является строкой. Однако в реальных приложениях почти всегда требуется
более строгая проверка: формат email, идентификатор, номер телефона, код
продукта или произвольный шаблон.
Для этого используется механизм сопоставления строки с регулярным выражением. Он позволяет описывать допустимые варианты символов и их порядок без необходимости писать императивную логику.
Ключевая идея заключается в том, что строка не просто должна быть текстом, но и соответствовать заранее заданному формату.
Основной инструмент для работы с шаблонами строк — функция
pattern.
Она применяется к уже существующей структуре строки и добавляет к ней ограничение в виде регулярного выражения.
Сигнатура выглядит следующим образом:
pattern(structure, regex)
Где:
structure — базовая структура, чаще всего
string()regex — регулярное выражение, которому должна
соответствовать строкаФункция возвращает новую структуру, которая проходит проверку только в случае соответствия строки указанному шаблону.
При валидации происходит последовательная проверка:
Важно, что регулярное выражение применяется ко всей строке целиком,
поэтому часто используются якоря ^ и $, чтобы
исключить частичные совпадения.
import { string, pattern } from 'superstruct'
const ZipCode = pattern(string(), /^[0-9]{6}$/)
Здесь допускаются только строки из ровно шести цифр. Любые буквы, пробелы или лишние символы приведут к ошибке.
const Username = pattern(string(), /^[a-zA-Z]+$/)
Такая структура разрешает только латинские буквы без цифр и символов.
const ProductCode = pattern(string(), /^[A-Z]{3}[0-9]{4}$/)
Пример формата: ABC1234. Первая часть — три заглавные
буквы, вторая — четыре цифры.
Регулярные выражения позволяют описывать значительно более сложные правила.
const Email = pattern(
string(),
/^[^\s@]+@[^\s@]+\.[^\s@]+$/
)
Хотя реальные email-адреса могут быть гораздо сложнее, такой шаблон используется для базовой проверки структуры.
const Slug = pattern(
string(),
/^[a-z0-9]+(?:-[a-z0-9]+)*$/
)
Этот шаблон часто применяется для SEO-дружественных идентификаторов:
my-product-name.
Строковые структуры в Superstruct могут комбинироваться с другими проверками, такими как длина или обязательность значения.
Пример комбинирования:
import { string, size, pattern } from 'superstruct'
const Username = size(
pattern(string(), /^[a-z0-9_]+$/),
3,
16
)
Здесь выполняется сразу несколько условий:
Проверки выполняются последовательно, что позволяет точно локализовать причину ошибки.
При несоответствии шаблону Superstruct возвращает структурированную ошибку. Она содержит:
Пример логики ошибки:
/^[0-9]{6}$/"12A45"Такая детализация важна при построении API, где необходимо возвращать понятные сообщения клиенту.
Регулярные выражения в pattern работают в
JavaScript-движке, поэтому важно учитывать особенности:
Флаг g не должен использоваться, поскольку он может
нарушить корректность повторных проверок.
Без ^ и $ проверка может стать
частичной:
pattern(string(), /[0-9]+/)
Такое выражение пропустит строку "abc123" — совпадение
будет найдено внутри строки. Поэтому корректнее:
pattern(string(), /^[0-9]+$/)
Структуры с pattern часто используются для входных
данных:
Пример структуры запроса:
const CreateOrderRequest = object({
userId: pattern(string(), /^[0-9]{8}$/),
coupon: optional(pattern(string(), /^[A-Z0-9]{6}$/))
})
Такой подход позволяет централизованно контролировать формат данных на границе системы.
В некоторых случаях один шаблон недостаточен. Тогда используется комбинация нескольких структур.
import { union, string, pattern } from 'superstruct'
const PhoneNumber = union([
pattern(string(), /^\+7\d{10}$/),
pattern(string(), /^8\d{10}$/)
])
Здесь допускаются два формата номера телефона:
Регулярные выражения могут быть созданы динамически:
function startsWith(prefix) {
return pattern(string(), new RegExp(`^${prefix}.*$`))
}
Такой подход позволяет строить переиспользуемые шаблоны на основе параметров.
Несмотря на гибкость, использование pattern имеет
особенности:
Поэтому в сложных случаях регулярные выражения используются только для базовой проверки формата, а бизнес-логика выносится отдельно.
При проектировании структур важно соблюдать баланс между строгостью и гибкостью:
string() должна присутствовать
всегдаpattern используется для формата, а не для
бизнес-правилПример разделения ответственности:
const RawCode = pattern(string(), /^[A-Z0-9]+$/)
const Code = size(RawCode, 6, 12)
Такой подход упрощает поддержку и повторное использование структур.
Регулярные выражения в Superstruct выполняются синхронно. При большом количестве проверок стоит учитывать:
Особенно это важно в системах с массовой обработкой входящих данных.