# Tuples

{% tabs %}
{% tab title="📘 手冊" %}
* TypeScript ⟩&#x20;
  * [Tuple Types](https://www.typescriptlang.org/docs/handbook/2/objects.html#tuple-types)
  * [readonly Tuple Types](https://www.typescriptlang.org/docs/handbook/2/objects.html#readonly-tuple-types)
  * [Variadic Tuple Types](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-4-0.html#variadic-tuple-types) (✳️ TS 4.0)
  * [Labeled Tuple Elements](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-4-0.html#labeled-tuple-elements) (✳️ TS 4.0)
{% endtab %}

{% tab title="👥 相關" %}
* [⭐️ Cheat sheet](../cheatsheet)
{% endtab %}
{% endtabs %}

{% hint style="info" %}
A _**tuple** type_ is a sort of [**Array**](generics/array) type that knows exactly **how many** elements it contains, and exactly **which types** it contains **at specific positions**.
{% endhint %}

## Cheatsheet

{% tabs %}
{% tab title="tuple" %}
```typescript
//          ╭── ⭐️ tuple ──╮
type Pair = [string, number];

function f(pair: Pair) {
  const a = pair[0];          // ⭐️ access elements by index
  const b = pair[1];
}

function f(pair: Pair) {
  const [a, b] = pair;        // ⭐️ by array destructuring
}
 
f(["hello", 42]);
```
{% endtab %}

{% tab title="optional?" %}
```typescript
// ⭐️ must be last            ╭─ ⭐️ ─╮
type Point = [number, number, number? ];
 
function f(point: Point) {
  const [x, y, z] = point;          // ⭐️ z: number | undefined
  console.log(`${point.length}`);   // ⭐️ length: 2 | 3
}
```
{% endtab %}

{% tab title="...rest" %}
```typescript
// ⭐️ rest element         ╭─ ⭐️ rest ─╮
type T1 = [string, number, ...boolean[] ];

// ⭐️ TypeScript 4.0 新功能：
// TS < 4.0 => T2 會產生："A rest element must be last in a tuple type"
type T2 = [string, ...boolean[], number];     // ⭐️ needn't be last

const a: T1 = ["hello", 1];
const b: T1 = ["beautiful", 2, true];
const c: T1 = ["world", 3, true, false, true, false, true];
```
{% endtab %}

{% tab title="Second Tab" %}

{% endtab %}
{% endtabs %}

## Optional elements

{% hint style="warning" %}
* can only come **at the end**&#x20;
* **affect** the **type** of **length**
{% endhint %}

```typescript
// ⭐️ must be last            ╭─ ⭐️ ─╮
type Point = [number, number, number? ];
 
function f(point: Point) {
  const [x, y, z] = point;          // ⭐️ z: number | undefined
  console.log(`${point.length}`);   // ⭐️ length: 2 | 3
}
```

## Rest elements

{% hint style="info" %}
* Tuples can have **rest elements**, which have to be an **array**/**tuple** type.
* A tuple with a **rest element** has **no set** “**length**” - it only has a set of well-known elements in different positions.
{% endhint %}

{% tabs %}
{% tab title="code" %}
```typescript
// ⭐️ rest element         ╭─ ⭐️ rest ─╮
type T1 = [string, number, ...boolean[] ];

// ⭐️ TypeScript 4.0 新功能：
// TS < 4.0 => T2 會產生："A rest element must be last in a tuple type"
type T2 = [string, ...boolean[], number];     // ⭐️ needn't be last

const a: T1 = ["hello", 1];
const b: T1 = ["beautiful", 2, true];
const c: T1 = ["world", 3, true, false, true, false, true];
```
{% endtab %}

{% tab title="CodeSandbox" %}
{% embed url="https://codesandbox.io/embed/tuple-rest-elements-yd3f3?expanddevtools=1&fontsize=14&hidenavigation=1&theme=dark" %}


{% endtab %}
{% endtabs %}

{% hint style="info" %}
Tuples types can be used in [rest parameters and arguments](https://www.typescriptlang.org/docs/handbook/2/functions.html#rest-parameters-and-arguments), so that the following:

```typescript
// rest param ↴
//         ╭─ ⭐️ ─╮ ╭── ⭐️ tuple with rest elem ──╮
function f(...args: [string, number, ...boolean[]]) {
  const [name, version, ...input] = args;
  // ...╰──── ⭐️ array destructuring ───╯
}
```

is basically equivalent to:

```typescript
function f(name: string, version: number, ...input: boolean[]) {
  // ...
}
```
{% endhint %}

## Variadic Tuple Types <a href="#variadic" id="variadic"></a>

```typescript
🚧 under construction ...
```

## Labeled Tuple Elements <a href="#labeled" id="labeled"></a>

```typescript
🚧 under construction ...
```
