В Superstruct структура объекта задаётся через комбинацию базовых
валидаторов и функции object, которая описывает форму
данных в виде набора полей и их типов. Такой подход позволяет явно
фиксировать контракт данных и проверять его на этапе выполнения.
Основная идея заключается в том, что объект рассматривается как набор ключей, каждому из которых соответствует отдельная структура (строка, число, вложенный объект, массив или пользовательское правило валидации).
Функция object принимает описание структуры и возвращает
валидатор, который проверяет соответствие входного значения заданной
схеме.
import { object, string, number } from 'superstruct'
const User = object({
name: string(),
age: number(),
})
В данном случае структура объекта строго фиксирует наличие двух полей:
name — строкаage — числоЛюбое отклонение от этой формы приведёт к ошибке валидации.
Каждое свойство объекта описывается отдельной структурой. Superstruct не делает неявных преобразований типов и требует явного соответствия.
const Post = object({
title: string(),
views: number(),
})
Объект считается валидным только при одновременном выполнении всех условий:
Одним из ключевых механизмов является возможность композиции структур, где объект содержит другие объекты.
const Address = object({
city: string(),
zip: number(),
})
const User = object({
name: string(),
address: Address,
})
Здесь структура User включает вложенный объект
address, который валидируется по собственной схеме.
Такой подход позволяет строить сложные иерархии данных без потери читаемости.
Для управления обязательностью используется валидатор
optional.
import { object, string, optional } from 'superstruct'
const Profile = object({
username: string(),
bio: optional(string()),
})
Поле bio может отсутствовать либо содержать строку. При
этом отсутствие поля не считается ошибкой.
Для работы с частичными данными применяется partial,
который делает все поля объекта необязательными.
import { object, string, number, partial } from 'superstruct'
const BaseUser = object({
name: string(),
age: number(),
})
const PartialUser = partial(BaseUser)
В результате PartialUser допускает наличие любого
подмножества полей исходной структуры.
Superstruct предоставляет механизмы для формирования производных структур:
import { object, string, pick } from 'superstruct'
const User = object({
name: string(),
age: string(),
email: string(),
})
const PublicUser = pick(User, {
name: true,
email: true,
})
import { omit } from 'superstruct'
const SafeUser = omit(User, {
email: true,
})
Эти операции позволяют переиспользовать базовые структуры без дублирования описаний.
По умолчанию Superstruct не строго запрещает наличие дополнительных ключей, однако поведение может регулироваться через дополнительные настройки и пользовательские проверки.
В типичных схемах структура рассматривается как декларация ожидаемых данных, а не как жёсткий фильтр входного объекта.
Структуры можно комбинировать, формируя сложные схемы из простых блоков.
const Contact = object({
email: string(),
phone: string(),
})
const Employee = object({
name: string(),
contact: Contact,
})
Такой подход снижает дублирование и позволяет централизовать описание повторяющихся сущностей.
Для более сложной логики валидации применяется refine,
позволяющий накладывать дополнительные ограничения на уже описанную
структуру.
import { object, string, refine } from 'superstruct'
const Password = refine(string(), 'Password', (value) => {
return value.length >= 8
})
При применении к объектам это позволяет проверять зависимости между полями.
Superstruct интегрируется с TypeScript через вывод типов на основе схемы.
import { Infer, object, string, number } from 'superstruct'
const User = object({
name: string(),
age: number(),
})
type UserType = Infer<typeof User>
UserType автоматически соответствует описанной структуре
и синхронизируется с валидатором.
Структуры объектов в Superstruct проектируются как независимые единицы, которые можно:
const Base = object({
id: number(),
})
const Extended = object({
...Base.schema,
name: string(),
})
Хотя прямое распространение схемы через spread используется реже, концептуально это отражает идею расширяемости.
Определение структуры объекта в Superstruct часто используется для описания доменных моделей:
Каждая структура выступает формальным описанием допустимого состояния данных.
При увеличении сложности системы структура объекта становится композиционной единицей архитектуры данных. Разделение схем на независимые блоки позволяет:
Структура объекта в Superstruct выступает явным контрактом между источником и потребителем данных. Любое несоответствие фиксируется на этапе выполнения, что позволяет контролировать целостность данных без скрытых преобразований.