Кортежи

Последнее обновление: 15.05.2021

Кортежи (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
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850