Работа с объектами в Superstruct строится вокруг декларативного описания схемы данных, где каждый ключ объекта явно связан с типом и правилами валидации. Объектная структура используется для описания JSON-подобных данных, конфигураций, DTO и любых вложенных сущностей, требующих строгой проверки формы.
Основой является функция object, принимающая описание
полей:
import { object, string, number } from 'superstruct'
const User = object({
name: string(),
age: number(),
})
Каждое свойство объекта описывается отдельным структурным типом. Валидация проходит рекурсивно: сначала проверяется сам объект, затем каждое поле.
По умолчанию объект в Superstruct является строгим по полям. Это означает, что наличие лишних ключей может считаться ошибкой в зависимости от режима использования.
const User = object({
name: string(),
})
validate({ name: 'Alex', extra: true }, User)
Лишние поля не участвуют в проверке структуры и могут быть отброшены или вызовут ошибку в зависимости от конфигурации обработки результата.
Все поля внутри object считаются обязательными, если не
указано иное.
optionalimport { object, string, optional } from 'superstruct'
const User = object({
name: string(),
nickname: optional(string()),
})
В этом случае поле nickname может отсутствовать без
нарушения структуры.
Для задания дефолтных значений используется defaulted.
Это позволяет автоматически заполнять отсутствующие поля.
import { object, string, defaulted } from 'superstruct'
const User = object({
name: string(),
role: defaulted(string(), 'user'),
})
Если поле role отсутствует, оно будет автоматически
заполнено значением 'user'.
Object-структуры могут быть произвольно вложенными, образуя сложные деревья данных.
import { object, string, number } from 'superstruct'
const Address = object({
city: string(),
zip: number(),
})
const User = object({
name: string(),
address: Address,
})
Каждый уровень вложенности валидируется независимо, что позволяет изолировать ошибки в конкретной части структуры.
Объекты можно комбинировать через переиспользование схем:
const BaseUser = object({
name: string(),
})
const AdminUser = object({
...BaseUser.schema,
permissions: string(),
})
Такой подход позволяет строить расширяемые модели данных без дублирования описаний.
Для создания объектов, где все поля становятся необязательными,
используется концепция частичной структуры через обёртки или ручное
применение optional.
const PartialUser = object({
name: optional(string()),
age: optional(number()),
})
Это особенно полезно для PATCH-операций и частичных обновлений данных.
Вложенные структуры проверяются глубоко. Ошибка может возникнуть на любом уровне:
const User = object({
profile: object({
email: string(),
}),
})
Если profile.email не соответствует типу
string, ошибка будет привязана к конкретному пути
вложенности.
При несоответствии данных схема возвращает структурированную ошибку, содержащую путь до проблемного поля.
Пример логики ошибки:
profile.emailЭто позволяет точно локализовать источник некорректных данных без дополнительного анализа входного объекта.
Object-структуры часто комбинируются с массивами:
import { array, object, string } from 'superstruct'
const User = object({
name: string(),
})
const Users = array(User)
Каждый элемент массива проходит отдельную проверку по схеме
User.
coerceОбъекты могут автоматически преобразовывать входные данные перед проверкой:
import { object, coerce, string, number } from 'superstruct'
const User = coerce(
object({
age: number(),
}),
object({
age: string(),
}),
(value) => ({
age: Number(value.age),
})
)
Это позволяет работать с “грязными” входными данными, например строковыми значениями чисел.
refine для объектных структурДля добавления пользовательских ограничений используется
refine:
import { object, string, refine } from 'superstruct'
const User = refine(
object({
password: string(),
confirm: string(),
}),
(value) => value.password === value.confirm
)
Если условие не выполняется, структура считается невалидной.
Когда структура объекта не фиксирована, используется
record:
import { record, string, number } from 'superstruct'
const Scores = record(string(), number())
Такой объект позволяет произвольные строковые ключи с числовыми значениями.
Object может комбинироваться с другими типами:
import { object, string, array, number } from 'superstruct'
const Team = object({
name: string(),
members: array(
object({
id: number(),
name: string(),
})
),
})
Такие структуры часто используются для описания API-ответов.
Superstruct не требует явного описания всех возможных ключей. Однако при строгих моделях данные, выходящие за пределы схемы, могут считаться избыточными.
Типичная стратегия обработки:
Объектная проверка выполняется последовательно по ключам. Производительность зависит от:
refine,
coerce)Оптимизация достигается через переиспользование схем и минимизацию избыточных проверок.
Объектные структуры в Superstruct применяются для:
Объектная модель Superstruct ориентирована на композицию. Сложные структуры собираются из простых типов, что снижает связность и упрощает повторное использование схем без дублирования логики проверки.