The Power of Tuples
This article will present uses of Typescript Tuples for developers using React and Angular.
A Tuple is an array with special properties and considerations:
- The number of elements of the array is fixed (aka immutable).
- The type of the elements of the array need not be the same.
- The type of each elements is known.
Consider the following tuples:
Here ^ the Point type is an array with the third element optional; the tuple could be used for 2D or 3D points.
Here ^ the TodoHook type is an custom Tuple. It is array with 3 elements: a string value, an array instance, and a service instance.
Problems with Arrays
Arrays contain 0…n elements of the same type. But if we want to use an array structure with elements that may be different types… how do we know which index has what object or value?
Tuples solve this issue. Here are some guidelines about Tuples:
- We do not care how the objects were created.
- We do not care why the element arrangement is in a certain ordering.
- We use TypeScript to identify the type of each element.
- We are focused on safely using the elements in the tuple.
Declaring the types of each element provides type-safety.
Why are Tuples important?
Tuples are useful in the following scenarios:
- A Tuple to define a single response from a function call
- A Tuple to group 2…n arguments inside a function call
Let’s explore each of these usages with real-world examples of tuples in React and Angular.
Functions returning Tuples
Function calls have a single response value for each call. When developers want to return multiple values they typically use an ‘object wrapper’ or an array.
But what happens when the API should return raw values, service instances, and perhaps even function references?
This is where Tuples shine!
1) React Standard Hooks return Tuples!
React has Hooks that allow developers to build Functional view components with state separated (and synced) from rendering. Consider the
Here we define a string value which will be used as state in rendering the functional component.
- The 1st element is the ‘current’ value for the
- The 2nd element is a setter function that will update the state.
setFirstNameis a setter function
(newValue: string) => void;
Why is this Tuple useful?
a) If we do not need the setter function, we can ignore it:
b) The developer can decide what variable names to use for each Tuple element when destructuring:
2) React Custom Hooks return Custom Tuples
Consider the React custom
useTodoHook that is used in the tutorial: RxJS Facades in React
Note that the hook declares a return tuple:
useTodosHook(): TodoHookTuple. The actual tuple contains two (2) raw values (
todos) and a reference to the
TodosPage functional component simply uses this tuple as follows:
With TypeScript Tuples defining the types, developers and IDE(s) can ensure that the values and the facade instance are being used correctly.
3) Custom Tuples in Angular
Consider a custom REST API in custom
TaskService class; where we want to use Promise(s) and
async/wait instead of Observables.
We can use Tuples to simultaneously return both the response or error.
Then we can easily use this:
Functions using Tuples
Function calls often have more than a single parameter. What if the function logic is simplified using the rest parameter syntax
... to gather some of the arguments as a Tuple?
A typical function like:
could be changed to:
The goal of the rest parameter syntax is to collect “argument overflow” into a single structure: an array or a tuple.
How is this different from just passing an array? In this example, a Tuple type forces us to pass a number for
z is optional.
- An array could be empty.
- A Tuple will throw an error if we are not passing at least 2 numbers to the draw function.
Notice that the length of each of the Point tuples varies by the number of elements the tuple has.
If you are interested in learning more about Tuples [and the
unknown type] read the excellent article “TypeScript 3.0: Exploring Tuples and the Unknown Type” by Dan Arias.