Кортежи в Yup представляют собой специализированную форму описания структур данных фиксированной длины, где каждый элемент имеет строго определённый тип и позиционное значение. В отличие от обычных массивов, где элементы одного типа или смешанного типа описываются единым набором правил, кортеж задаёт жёсткую схему для каждой позиции, формируя предсказуемую и детерминированную структуру данных.
В библиотеке Yup кортежи реализуются через yup.tuple,
принимающий массив схем, каждая из которых соответствует конкретному
индексу. Это позволяет описывать данные, где порядок элементов
критически важен и несёт смысловую нагрузку.
Кортеж задаётся как последовательность схем:
import * as yup from 'yup';
const schema = yup.tuple([
yup.string(),
yup.number(),
yup.boolean()
]);
В данном случае ожидается массив ровно из трёх элементов:
Любое отклонение от этой структуры приводит к ошибке валидации.
Обычный массив в Yup описывается через
yup.array().of(schema), где все элементы подчиняются одной
схеме:
const arraySchema = yup.array().of(yup.string());
Кортеж же фиксирует структуру по позициям:
const tupleSchema = yup.tuple([
yup.string(),
yup.string(),
yup.string()
]);
Если массив гибок и ориентирован на коллекции однотипных данных, то кортеж предназначен для строго структурированных наборов, где каждая позиция имеет самостоятельную семантику.
При валидации Yup проверяет каждый элемент по соответствующей позиции:
const schema = yup.tuple([
yup.string().required(),
yup.number().min(0),
yup.boolean()
]);
schema.validate(['test', 42, true]);
Если хотя бы один элемент не соответствует своей схеме, валидация завершается ошибкой. Например:
schema.validate(['test', -5, true]);
Во втором элементе нарушено условие min(0), что делает
весь кортеж невалидным.
Кортеж в Yup по умолчанию предполагает фиксированную длину. Это означает, что:
const schema = yup.tuple([
yup.string(),
yup.number()
]);
schema.validate(['a']); // ошибка: не хватает элемента
schema.validate(['a', 1, 2]); // ошибка: лишний элемент
Такая строгость делает кортежи полезными для описания протоколов, конфигураций и структурированных ответов API.
Несмотря на строгую природу, отдельные позиции могут быть сделаны необязательными:
const schema = yup.tuple([
yup.string().required(),
yup.number().notRequired(),
yup.boolean().notRequired()
]);
В этом случае допускается undefined на позициях, где
указано notRequired.
Пример допустимого значения:
['hello']
['hello', 10]
['hello', 10, false]
Каждый элемент кортежа может принимать null, если явно
разрешить это:
const schema = yup.tuple([
yup.string().nullable(),
yup.number().nullable()
]);
Теперь допустимы значения:
['text', null]
[null, 5]
Кортежи Yup тесно интегрируются с TypeScript, позволяя выводить строгие типы:
const schema = yup.tuple([
yup.string(),
yup.number(),
yup.boolean()
]);
type Result = yup.InferType<typeof schema>;
// Result: [string, number, boolean]
Это особенно важно для приложений, где требуется строгая контрактная модель данных.
Кортежи могут быть вложенными, формируя сложные структуры:
const schema = yup.tuple([
yup.string(),
yup.tuple([
yup.number(),
yup.boolean()
])
]);
Пример валидного значения:
['id', [42, true]]
Такая композиция позволяет описывать сложные протоколы обмена данными, где часть структуры также имеет фиксированную позиционную модель.
Каждый элемент кортежа может иметь собственные трансформации:
const schema = yup.tuple([
yup.string().trim(),
yup.number().transform(value => Number(value))
]);
В этом случае входные данные нормализуются до прохождения финальной проверки.
При использовании методов частичной проверки
(validateAt) можно проверять конкретную позицию
кортежа:
schema.validateAt('[1]', ['test', 'not-a-number']);
Это позволяет изолировать ошибки в конкретных элементах структуры.
Кортежи часто применяются для описания фиксированных структур конфигураций, например:
const endpointSchema = yup.tuple([
yup.string(), // URL
yup.string(), // метод
yup.number() // таймаут
]);
Пример данных:
['/api/users', 'GET', 5000]
Каждая позиция здесь имеет строго определённую роль, и нарушение порядка полностью меняет смысл данных.
В некоторых случаях кортеж можно заменить объектом:
{
url: string,
method: string,
timeout: number
}
Однако кортежи предпочтительны, когда:
Ошибки в кортежах Yup всегда привязаны к индексу элемента:
tuple[0] — ошибка первого элемента,tuple[1] — ошибка второго и так далее.Это упрощает отладку сложных структур, так как источник ошибки точно локализован.
Кортежи могут использоваться внутри более сложных схем:
const schema = yup.object({
meta: yup.tuple([
yup.string(),
yup.number()
]),
tags: yup.array(yup.string())
});
Такая композиция позволяет сочетать фиксированные и динамические структуры данных в одной модели.
При сериализации кортежи не отличаются от массивов на уровне JavaScript, однако схема Yup накладывает дополнительный слой интерпретации, который определяет смысл каждого индекса. Это различие критично: структура внешне выглядит как массив, но поведение строго позиционное.
Кортежи в Yup имеют ряд ограничений:
По этой причине они используются преимущественно там, где структура данных заранее известна и не изменяется во времени.