Кортежи (Tuples) также, как и массивы, представляют набор элементов, для которых уже заранее известен тип. В отличие от массивов кортежи могут хранить значения разных типов. Для определения кортежа применяется синтаксис массива:
// определение кортежа - кортеж состоит из двух элементов - строки и числа let user: [string, number];
В данном случае кортеж user
представляет тип [string, number]
, то есть такой кортеж, который состоит из двух элементов, при чем
первый элемент представляет тип string
, а второй элемент - тип number
.
Для присвоения значения применяется массив:
user = ["Tom", 28];
Причем передаваемые кортежу данные должны соответствовать элементам по типу. Например, ниже неправильный пример инициализации кортежа;
// Неправильная инициализация - переданные значения не соответствуют типам по позиции //userInfo = [28, "Tom"]; // Ошибка
Для обращения к элементам кортежа, так же как и для массива, применяются индексы:
let user: [string, number] = ["Tom", 36]; console.log(user[1]); // 36 user[1] = 37; console.log(user[1]); // 37
С помощью цикла for можно перебрать элементы кортежа:
let user: [string, number] = ["Tom", 36]; for(const prop of user){ console.log(prop); }
Кортежи как параметры функции:
function printUser(user: [string, number]) { console.log(user[0]); console.log(user[1]); } let tom: [string, number] = ["Tom", 36]; printUser(tom);
Кортеж как результат функции:
function createUser(name: string, age: number) : [string, number]{ return [name, age]; } let user = createUser("Bob", 41); console.log(user[0]); console.log(user[1]);
Кортежи могут иметь необязательные элементы, для которых можно не предоставлять значение. Чтобы указать, что элемент является необязательным, после типа элемента ставится вопросительный знак ?:
let bob: [string, number, boolean?] = ["Bob", 41, true]; let tom: [string, number, boolean?] = ["Tom", 36];
В данном случае последний элемент, который представляет тип boolean
, необязательный. Причем необязательные элементы должны идти в самом конце - после обязательных элементов.
Кортеж с необязательными элементами как параметр функции:
function printUser(user: [string, number, boolean?]) { if(user[2]!==undefined){ console.log(`name: ${user[0]} age: ${user[1]} isMarried: ${user[2]}`); } else{ console.log(`name: ${user[0]} age: ${user[1]}`); } } let bob: [string, number, boolean] = ["Bob", 41, true]; let tom: [string, number] = ["Tom", 36]; printUser(bob); printUser(tom);
Стоит отметить, что здесь кортеж tom
представляет тип [string, number]
и также соответствует типу [string, number, boolean?]
,
поскольку последний элемент является необязательным.
С помощью оператора ... внутри определения типа кортежа можно определить набор элементов, количество которых неопределено. Например:
let math: [string, ...number[]] = ["Math", 5, 4, 5, 4, 4]; let physics: [string, ...number[]] = ["Physics", 5, 5, 5];
В данном случае оба кортежа представляют тип [string, ...number[]]
. То есть первый элемент кортежа должен представлять тип string
. А остальные
элементы кортежа должны представлять тип number
, причем таких элементов может быть неопределенное количество.
Кортеж с неопределенным количеством элементов в качестве параметра функции:
function printMarks(marks: [string, ...number[]]){ for(const mark of marks){ console.log(mark); } } let math: [string, ...number[]] = ["Math", 5, 4, 5, 4, 4]; let physics: [string, ...number[]] = ["Physics", 5, 5, 5]; printMarks(math); printMarks(physics);
При этом неопределенное количество элементов можно определять как в конце, так и в середине и в начале кортежа:
let math: [string, ...number[]] = ["Math", 5, 4, 5, 4, 4]; let physics: [...number[], string] = [5, 5, 5, "Physics"]; let chemistry: [string, ...number[], boolean] = ["Chemistry", 3, 3, 4, 5, false];
В случае с кортежем [...number[], string]
он должен оканчиваться на элемент типа string
, перед которым может быть неопределенное количество элементов
типа number
.
А в кортеже типа [string, ...number[], boolean]
первый элемент должен представлять тип string
,
а последний - тип boolean
. Между ними может быть неопределенное количество элементов типа number
.
Стандартные кортежи позволяют изменять значения их элементов:
const tom: [string, number] = ["Tom", 36]; tom[1] = 37; console.log(tom[1]); // 37
Однако TypeScript также позволяет создавать кортежи только для чтения, элементы которого нельзя изменить. Для этого перед типом кортежа указывается ключевое слово readonly:
const tom: readonly [string, number] = ["Tom", 36]; tom[1] = 37; // ! Ошибка - элементы кортежа для чтения нельзя изменять
Кортеж для чтения в качестве параметра функции:
function printUser(user: readonly [string, number]) { console.log(`name: ${user[0]} age: ${user[1]}`); }
Кортеж для чтения в качестве результата функции:
function generateUser(): readonly [string, number]{ return ["Sam", 18]; }
Кортеж, как и массив, можно раскладывать на переменные и константы:
let tom: [string, number, boolean] = ["Tom", 36, false]; let [username, userage, isMarried] = tom; // декомпозиция console.log(username); // Tom console.log(userage); // 36 console.log(isMarried); // false
Здесь кортеж tom
раскладывается на три переменных: username, userage, isMarried. При этом количество переменных должно соответствовать
количеству элементов кортежа.
С помощью оператора ... можно указать кортеж, в который будут помещаться все оставшиеся элементы раскладываемого кортежа, которые не вошли в предыдущие переменные или константы:
let tom: [string, number, boolean] = ["Tom", 36, false]; const [username, ...rest] = tom; console.log(username); // Tom console.log(rest[0]); // 36 console.log(rest[1]); // false
Здесь константа username
также принимает первый элемент кортежа - "Tom". Все оставшиеся элементы кортежа будут помещаться в кортеж rest
.
Мы можем определить меньше переменных/констант, чем элементов в кортеже, тогда оставшиеся элементы кортежа будут игнорироваться:
let tom: [string, number, boolean] = ["Tom", 36, false]; const [username, userage] = tom; console.log(username); // Tom console.log(userage); // 36
Также можно оставить пустое место вместо переменной/константы, если мы хотим пропустить соответствующий элемент кортежа:
let tom: [string, number, boolean, number] = ["Tom", 36, false, 170]; const [, age, , height] = tom; // пропускаем первый и третий элементы console.log(age); // 36 console.log(height); // 170