В библиотеке Superstruct структура never представляет
собой специальный тип, который всегда приводит к ошибке
валидации независимо от входного значения. Это не просто
ограничение или частный случай проверки — это явное выражение
невозможности значения в системе типов и валидации.
Структура never используется для описания
логически недостижимых состояний данных. Любое
значение, переданное в такую структуру, считается некорректным.
Ключевые свойства:
Фактически never — это декларация запрета на любые
данные.
При проверке значения через never всегда возникает
ошибка.
import { assert, never } from 'superstruct'
assert(123, never) // ошибка
assert('text', never) // ошибка
assert(null, never) // ошибка
assert(undefined, never) // ошибка
assert({}, never) // ошибка
Любая попытка валидации приводит к исключению, поскольку структура не допускает ни одного возможного значения.
Один из практических сценариев — явное запрещение определённых ключей в объектных структурах.
import { object, string, never } from 'superstruct'
const User = object({
id: string(),
password: never(),
})
В этом случае:
id допустим и должен быть строкойpassword полностью запрещёнЛюбое наличие password в объекте делает структуру
невалидной.
В TypeScript и аналогичных системах тип never
используется для описания невозможных веток. Superstruct поддерживает
аналогичную семантику на уровне данных.
Пример:
const Response = object({
status: string(),
data: never(),
})
Такой объект невозможно корректно создать с полем
data.
never часто используется внутри объединений для
исключения вариантов.
import { union, string, number, never } from 'superstruct'
const Value = union([string(), number(), never()])
С точки зрения логики:
string допустимnumber допустимnever не добавляет новых возможностейФактически он становится нейтральным исключающим элементом, не влияющим на множество допустимых значений.
При проектировании API never может использоваться для
явного запрета полей, которые не должны приходить от клиента.
const Request = object({
query: string(),
debug: never(),
internalToken: never(),
})
Любая попытка передать debug или
internalToken приводит к ошибке валидации.
Это позволяет:
optional и
nullВажно различать never и другие ограничения:
optionalПоле может отсутствовать, но если присутствует — валидируется.
nullableПоле может быть null, но остальные значения проходят
проверку.
neverПоле не может существовать вообще.
import { optional, nullable, never, string, object } from 'superstruct'
const Example = object({
a: optional(string()),
b: nullable(string()),
c: never(),
})
Поведение:
a можно не указыватьb можно сделать nullc запрещено полностьюВ экосистеме TypeScript never означает отсутствие
значений. Superstruct переносит эту концепцию на уровень
runtime-валидации.
Это позволяет:
never часто используется для отключения определённых
вариантов в union-структурах.
import { union, object, literal, never } from 'superstruct'
const Shape = union([
object({
type: literal('circle'),
radius: number(),
}),
object({
type: literal('square'),
side: number(),
}),
object({
type: literal('triangle'),
side: number(),
}),
object({
type: literal('broken'),
data: never(),
}),
])
Вариант broken становится недостижимым в корректных
данных и служит для:
Если never используется внутри validate, он
всегда возвращает ошибку независимо от контекста.
import { validate, never } from 'superstruct'
const [error] = validate('anything', never)
console.log(error) // всегда существует
Использование never в схемах — это не просто запрет, а
способ выразить структурную невозможность данных.
Он полезен в ситуациях, когда:
При использовании трансформирующих структур never может
служить фильтром, который исключает данные на раннем этапе.
import { assign, object, string, never } from 'superstruct'
const Struct = object({
name: string(),
removed: never(),
})
const Safe = assign(Struct, Struct)
Любая попытка трансформации с removed прерывает процесс
валидации.
Хотя never не допускает данных, он полезен как часть
документации схемы: