Tuple представляет собой структуру данных с заранее известным количеством элементов, где каждый элемент имеет строго определённый тип и порядок. В отличие от массивов, допускающих произвольную длину, tuple описывает фиксированную последовательность значений, что делает его особенно полезным для моделирования строго типизированных наборов данных.
В Superstruct tuple создаётся через функцию tuple,
принимающую набор структур:
import { tuple, string, number, boolean } from 'superstruct'
const Point = tuple([number(), number()])
В данном примере описана структура двумерной точки, где:
Использование tuple для валидации позволяет гарантировать точное соответствие формы данных:
import { assert } from 'superstruct'
assert([10, 20], Point) // валидно
assert([10], Point) // ошибка
assert([10, 20, 30], Point) // ошибка
Tuple строго проверяет не только типы, но и количество элементов.
Ключевая особенность tuple — позиционная типизация. Каждый индекс массива соответствует конкретному типу:
const UserRecord = tuple([
string(), // имя
number(), // возраст
boolean() // активен ли пользователь
])
Пример корректных данных:
['Alex', 28, true]
Любое отклонение от порядка или типов приводит к ошибке:
['Alex', true, 28] // нарушение порядка типов
Tuple может включать другие tuple, формируя сложные структуры данных:
const Point3D = tuple([number(), number(), number()])
const Line = tuple([
Point3D,
Point3D
])
Данные:
[
[0, 0, 0],
[10, 10, 10]
]
Такая модель часто используется в графике, геометрии и математических вычислениях.
Tuple может содержать любые структуры Superstruct, включая
object, array, union:
import { object, tuple, string, number } from 'superstruct'
const Response = tuple([
number(),
object({
status: string(),
message: string()
})
])
Пример валидных данных:
[
200,
{
status: 'ok',
message: 'success'
}
]
Tuple часто применяется при строгой проверке входных параметров:
import { create } from 'superstruct'
const Config = tuple([
string(),
number()
])
function init(config) {
const [name, timeout] = create(config, Config)
return {
name,
timeout
}
}
Здесь гарантируется, что входные данные всегда соответствуют ожидаемой сигнатуре.
При несоответствии структуры Superstruct формирует детализированную ошибку:
import { validate } from 'superstruct'
const [error, result] = validate(['test'], tuple([string(), number()]))
error будет содержать информацию о:
Хотя tuple ориентирован на фиксированную длину, можно использовать
optional для частичной гибкости:
import { optional, tuple, string, number } from 'superstruct'
const Flexible = tuple([
string(),
optional(number())
])
Допустимые значения:
['name']
['name', 123]
При этом порядок элементов остаётся строго фиксированным.
Tuple часто применяется вместо объектов, когда важна компактность и позиционная семантика:
// объектный вариант
{
x: 10,
y: 20
}
// tuple вариант
[10, 20]
Преимущества tuple:
Недостатки:
Tuple удобен для описания контрактов, где важна строгая сигнатура:
const HttpResponse = tuple([
number(), // статус код
string(), // тело ответа
boolean() // флаг кеширования
])
Такая модель фиксирует структуру ответа без двусмысленности.
Обычный массив:
array(number())
Tuple:
tuple([number(), string()])
Tuple наиболее уместен в случаях:
Пример RGB:
const RGB = tuple([
number(), // R
number(), // G
number() // B
])
Несмотря на гибкость Superstruct, tuple сохраняет строгие ограничения:
Эти ограничения являются частью его концепции строгой типизации данных на уровне рантайма.