Tuple Type

JavaScript doesn’t have first class tuple support. People generally just use an array as a tuple. This is exactly what the TypeScript type system supports. Tuples can be annotated using : [typeofmember1, typeofmember2] etc. A tuple can have any number of members. Tuples are demonstrated in the below example:

var nameNumber: [string, number]; // Okay nameNumber = ['Jenny', 8675309]; // Error! nameNumber = ['Jenny', '867-5309'];

Combine this with the destructuring support in TypeScript, tuples feel fairly first class despite being arrays underneath:

var nameNumber: [string, number]; nameNumber = ['Jenny', 8675309]; var [name, num] = nameNumber;

Variadic Tuple Types

Variadic Tuple Types are a features introduces in TypeScript version 4.0, let’s start to learn them by revise what is a tuple:

A tuple type is an array which has a defined length, and were the type of each element is known:

type Student = [string, number]; const [name, age]: Student = ['Simone', 20];

The term “variadic” means indefinite arity (accept a variable number of arguments).

A variadic tuple is a tuple type which has all the property as before but the exact shape is not defined yet:

type Bar<T extends unknown[]> = [boolean, ...T, number]; type A = Bar<[boolean]>; // [boolean, boolean, number] type B = Bar<['a', 'b']>; // [boolean, 'a', 'b', number] type C = Bar<[]>; // [boolean, number]

In the previous code we can see that the tuple shape is defined by the T generic passed in.

Variadic tuples can accept multiple generics make them very flexible:

type Bar<T extends unknown[], G extends unknown[]> = [...T, boolean, ...G]; type A = Bar<[number], [string]>; // [number, boolean, string] type B = Bar<['a', 'b'], [boolean]>; // ["a", "b", boolean, boolean]

With the new variadic tuples we can use:

  • The spreads in tuple type syntax can now be generic, so we can represent higher-order operation on tuples and arrays even when we do not know the actual types we are operating over.
  • The rest elements can occur anywhere in a tuple.

Example:

type Items = readonly unknown[]; function concat<T extends Items, U extends Items>( arr1: T, arr2: U ): [...T, ...U] { return [...arr1, ...arr2]; } concat([1, 2, 3], ['4', '5', '6']); // [1, 2, 3, "4", "5", "6"]