What is Tuple in TypeScript
Tags: typescript, learningtypescript, beginners
Published: 2023-03-15 18:13:13

## Intro

As I have mentioned multiple times in my previous articles that I have been learning TypeScript with the great book, "[Learning TypeScript](https://www.oreilly.com/library/view/learning-typescript/9781098110321/?_gl=1*afxut*_ga*NTE1MjkzMTQxLjE2Nzc4NzgwOTg.*_ga_092EL089CH*MTY3Nzg3ODA5OC4xLjEuMTY3Nzg3ODEwNS41My4wLjA.)".

And during my journey to review and learn TypeScript, I could meet an unfamiliar topic in TypeScript; Tuple. With the motivation to understand unknown things more clearly, I determined to write a new article about the fundamentals of Tuple.

## What is Tuple all about?

Tuple is a special method in TypeScript to specify the pre-defined lengths of arrays as well as the type of each element in arrays. All values in arrays with Tuple type are assigned value type based on the index of Tuple arrays. 

For example, in the code snippet below, personNameAndAge variable has an array with two values that have designated types based on the index number of that array respectively.

That means it is mandatory for us to pass exactly two elements to personNameAndAge variable. Otherwise, TypeScript will complain about wrong number of values in fixed length of array (Array with Tuple type).

```typescript
// Declare a variable with Tuple type
// personNameAndAge must have two values; 
// The first one (index 0) is string type and the second one (index 1) is number type
let personNameAndAge:[string, number]

personNameAndAge = ["Jason Adam", 33]  // Ok
personNameAndAge = ["Mark DeRosa"]  // Error: Type '[string]' is not assignable to type '[string, number]'. Source has 1 element(s) but target requires 2.
personNameAndAge = ["Lance Lynn", 20, "male"]  // Error: Type '[string, number, string]' is not assignable to type '[string, number]'. Source has 3 element(s) but target allows only 2.
```
We can also use Tuple type for the parameters of functions. Here is a simple code snippet describing it.

```typescript
// Declare a function returning three animal names
// The parameter of this function (animals) has fixed lengths (3)
function getThreeAnimals(animals: [string, string, string]): string {
  return `1: ${animals[0]}, 2: ${animals[1]}, 3: ${animals[2]}`;
}

const printedThreeAnimals = getThreeAnimals(['cat', 'dog', 'seal'])
console.log(printedThreeAnimals);  // Output: "1: cat, 2: dog, 3: seal"
```
## Assignability of Tuple

In addition to checking the fixed lengths of values in an array, Tuple type in TypeScript identifies type assignability and complains about it when a different value type is assigned to one of the elements or more in an array.

```typescript
let personNameAndAge:[string,number]
personNameAndAge = ["David Bednar", false]  // Error: Type 'boolean' is not assignable to type 'number'.
```
We have another case regarding the assignability of Tuple for variables. It could be confused when we use both an array with multiple value types and that with Tuple.

Since Tuple type narrows down the possibility of values in an array compared to a general array without Tuple, we cannot assign a variable defined as a regular array to another one declared with Tuple type. 

In other words, in terms of regular arrays, it is possible to have the number of elements in them whatever we want, while arrays with Tuple type are allowed to possess the exact number of elements that equals to the length of Tuple type.

```typescript
// Tuple is more specific than a regular array (It is impossible to assign Tuple type to a variable length array)
// In this case, personNameWithAge is recognized as a general array so TypeScript complains about the assignability
const personNameWithAge = ['Nick Martinez',40]
const newPersonNameWithAge:[string, number] = personNameWithAge  // Error: Type '(string | number)[]' is not assignable to type '[string, number]'. Target requires 2 element(s) but source may have fewer.

// anotherPersonNameWithAge variable with Tuple has a fixed length of array (It is more specific than a variable length array)
const anotherPersonNameWithAge:[string, number] = ['Nick Martinez',40]
const anotherNewPersonNameWithAge:[string, number] = anotherPersonNameWithAge  // Ok
```

## Read-only Tuple

Tuple type is beneficial for inferring an array literal as the read-only values. Generally, we can use “a const assertion” syntax replaced after declared variables to imply that they have the "readonly" prefix.

This "readonly" keyword in TypeScript infers us that variables with it are accessible but cannot be mutated at all.

```typescript
// Declare a general variable length array 
const generalArray = ['a','b',1,2]  // Type: (string | number)[]
// We can change the value of elements in this array
generalArray[1] = 'c';
console.log(generalArray);  // Output: ['a','c',1,2] 

// Define an array with a constant assertion (assigning Tuple type)
const readonlyArray = ['a','b',1,2] as const  // Type: readonly ['a', 'b', 1, 2]
readonlyArray[3] = 5  // Error: Cannot assign to '3' because it is a read-only property.
```

## Conclusion

Tuple type in TypeScript is a method to pre-define fixed lengths of arrays. It also strictly specifies the order of type values in an array by index number. (Tuple type makes sure that every value in an array has a corresponding value type in Tuple)

A useful case for Tuple is to create an array of a read-only, unchangeable variable. With the constant assertion (as constant) to regular arrays, we can restrict mutations to them (we can only refer to values in arrays).

## References

- [Learning TypeScript](https://www.oreilly.com/library/view/learning-typescript/9781098110321/?_gl=1*afxut*_ga*NTE1MjkzMTQxLjE2Nzc4NzgwOTg.*_ga_092EL089CH*MTY3Nzg3ODA5OC4xLjEuMTY3Nzg3ODEwNS41My4wLjA.)
- [TypeScript Tuples](https://www.w3schools.com/typescript/typescript_tuples.php#:~:text=A%20tuple%20is%20a%20typed,a%20known%20type%20of%20value.)