# Кортежи в TypeScript

Иногда у нас может возникнуть необходимость хранить массив значений различных типов. TypeScript предоставляет нам такой тип данных, называемый кортеж (англ. tuple).

Кортеж представляет собой массив, каждый элемент которого имеет свой жестко заданный тип. Для примера сделаем кортеж, в котором мы будем хранить имя и возраст юзера.

В первом элементе кортежа у нас будет имя и оно будет являться строкой, а во втором элементе у нас будет возраст и он будет являться числом. Давайте объявим описанный кортеж:

`let user: [string, number];`

Давайте при объявлении заполним наш кортеж данными:

`let user: [string, number] = ['john', 31];`

Давайте выведем элементы нашего кортежа:

`console.log(user[0]); // 'john' console.log(user[1]); // 31`

Сделайте кортеж, который будет хранить номер года и номер месяца.

Сделайте кортеж, который будет хранить номер года и название месяца.

Сделайте кортеж, который будет хранить номер года, номер месяца и номер дня.

## Изменение кортежа

Элементы кортежа можно изменять. Сделаем это:

`user[0] = 'eric'; console.log(user);`

Попытка записать записать в элемент кортежа значение другого типа приведет к ошибке:

`user[0] = 12; // ошибка`

Расскажите, каким будет результат выполнения следующего кода:

`let time: [number, number, number] = [12, 59, 59]; time[0] = 13; console.log(time);`

Расскажите, каким будет результат выполнения следующего кода:

`let time: [number, number, number] = [12, 59, 59]; time[0] = '01'; console.log(time);`

## Кортеж для чтения

Можно создавать кортежи только для чтения, элементы которого нельзя изменить. Для этого перед типом кортежа указывается ключевое слово `readonly`:

`let user: readonly [string, number] = ['john', 31];`

Попытка изменить такой кортеж приведет к ошибке:

`user[0] = 'eric'; // ошибка`

Расскажите, каким будет результат выполнения следующего кода:

`let time: readonly [number, number, number] = [12, 59, 59]; time[0] = 13; console.log(time);`

## Необязательные элементы кортежей

Кортежи могут иметь необязательные элементы, для которых можно не предоставлять значение. Чтобы указать, что элемент является необязательным, после типа элемента ставится вопросительный знак.

Для примера в кортеже с юзером сделаем еще один необязательный элемент:

`let user: [string, number, boolean?];`

Давайте заполним наш кортеж, указав третий элемент:

`user = ['john', 31, true];`

А теперь заполним кортеж, опустив третий элемент:

`user = ['john', 31];`

Заполните данными следующий кортеж:

`let date: [number, number?, number?];`

## Деструктуризация кортежа

Кортеж, подобно массиву, может быть подвергнут деструктуризации. Пусть для примера у нас есть вот такой кортеж:

`let user: [string, number] = ['john', 31];`

Давайте разобьем его части в переменные:

`let [name, age] = user;`

Дан следующий кортеж:

`let time: [number, number, number] = [12, 59, 59];`

Разбейте части времени в отдельные переменные.

## Заполнение кортежа

С помощью оператора rest в кортеже можно определить набор элементов, состоящий из произвольного количества значений, имеющих один тип.

Для примера давайте сделаем кортеж, в к котором первым элементом должна быть строка, а затем будет следовать произвольное количество чисел:

`let tpl: [string, ...number[]];`

Заполним наш кортеж данными:

`tpl = ['str', 1, 2, 3, 4, 5];`

Заполните данными следующий кортеж:

`let tpl: [string, string, ...number[]];`

Заполните данными следующий кортеж:

`let tpl: [number, boolean, ...string[]];`
←→
↑