Валидация строк в Superstruct строится вокруг базового структурного
типа string(), который задаёт фундаментальное правило:
значение должно быть строкой JavaScript. Любые дальнейшие ограничения
накладываются поверх этого базового инварианта через композицию
функций.
Базовая структура:
import { string } from "superstruct";
const Name = string();
На этом уровне структура допускает любое строковое значение, включая пустую строку и строки с пробелами. Все дополнительные правила вводятся отдельно и не являются частью базовой проверки.
Основная ответственность string() — гарантировать, что
значение соответствует примитивному типу string.
Примеры допустимых значений:
"hello""""123""строка с пробелами"Недопустимые значения:
123truenullundefined{}Проверка строго типизирована и не выполняет автоматического преобразования типов.
Для управления длиной строки используется функция size,
которая позволяет задать минимальную и максимальную границу.
import { string, size } from "superstruct";
const Username = size(string(), 3, 20);
Здесь накладываются правила:
Поведение при нарушении:
Использование size удобно в случаях, когда требуется
единое ограничение диапазона, например для логинов или кодов
подтверждения.
Частый случай — запрет пустых строк. В Superstruct это реализуется
через refine.
import { string, refine } from "superstruct";
const NonEmptyString = refine(string(), "NonEmptyString", (value) => {
return value.length > 0;
});
Функция refine позволяет добавить произвольную
бизнес-логику поверх базового типа.
Ключевые особенности:
Расширенный вариант часто включает также проверку пробельных строк:
const StrictNonEmptyString = refine(string(), "StrictNonEmptyString", (value) => {
return value.trim().length > 0;
});
Для формальной валидации форматов применяется
pattern.
import { string, pattern } from "superstruct";
const Email = pattern(
string(),
/^[^\s@]+@[^\s@]+\.[^\s@]+$/
);
pattern проверяет соответствие строки регулярному
выражению без преобразования значения.
Типичные сценарии:
Пример UUID:
const UUID = pattern(
string(),
/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i
);
coerceВ реальных приложениях часто требуется привести входные данные к
строке перед валидацией. Для этого используется coerce.
import { string, coerce } from "superstruct";
const StringFromAny = coerce(string(), (value) => {
if (typeof value === "string") return value;
if (value == null) return "";
return String(value);
});
Механика:
string()Типичные применения:
Для строковых структур возможно задание значения по умолчанию через
defaulted.
import { string, defaulted } from "superstruct";
const OptionalName = defaulted(string(), "anonymous");
Поведение:
"anonymous"Важно учитывать, что значение по умолчанию не обходится валидацией, а используется как валидное значение по контракту структуры.
Superstruct позволяет свободно комбинировать модификаторы. Это формирует декларативные цепочки правил.
Пример комплексной структуры:
import { string, size, pattern, refine } from "superstruct";
const Username = refine(
pattern(size(string(), 3, 16), /^[a-zA-Z0-9_]+$/),
"Username",
(value) => !value.startsWith("_")
);
Здесь применяются сразу несколько уровней:
_)Строковые данные часто требуют предварительной очистки. Superstruct
не навязывает автоматическую нормализацию, но позволяет встроить её
через coerce.
const TrimmedString = coerce(string(), (value) => {
if (typeof value !== "string") return value;
return value.trim();
});
Дальнейшие проверки выполняются уже на нормализованном значении.
Расширенный вариант:
const CleanString = coerce(string(), (value) => {
if (typeof value !== "string") return value;
return value.trim().replace(/\s+/g, " ");
});
Такой подход используется для:
Одно из ключевых свойств Superstruct — возможность композиции структур без потери читаемости логики.
Пример повторного использования:
const BaseString = string();
const ShortText = size(BaseString, 0, 50);
const LongText = size(BaseString, 0, 500);
Такой подход позволяет:
При нарушении правил string-структуры возвращается
объект ошибки, содержащий:
Пример сценария:
42Результат:
При использовании refine или pattern
добавляется дополнительный уровень детализации причины.
Superstruct поддерживает расширение типов через optional
и nullable.
import { string, optional, nullable } from "superstruct";
const OptionalString = optional(string());
const NullableString = nullable(string());
Различия:
optional — значение может отсутствоватьnullable — значение может быть nullКомбинирование:
const FlexibleString = optional(nullable(string()));
Строковые структуры применяются во всех слоях приложений:
API-валидация
Формы
Хранение данных
Интеграции
Когда стандартных средств недостаточно, применяется
refine с расширенной логикой.
Пример проверки домена:
const DomainString = refine(string(), "DomainString", (value) => {
return value.includes(".");
});
Или более строгий вариант:
const SafeString = refine(string(), "SafeString", (value) => {
return !/[<>]/.test(value);
});
Такой подход позволяет строить доменно-ориентированные ограничения поверх базового типа строки без изменения ядра библиотеки.