Tuplas - TypeScript
As tuplas(tuples), assim como os arrays, representam um conjunto de elementos cujo tipo é previamente conhecido. Ao contrário dos arrays, as tuplas podem armazenar valores de tipos diferentes. Para definir uma tupla, utilizamos a sintaxe de array:
// definição de uma tupla - a tupla consiste de dois elementos: uma string e um número
let user: [string, number];
Nesse caso, a tupla user representa o tipo [string, number]
string
number
Para atribuir um valor, usamos um array:
user = ["Tom", 28];
Os dados passados para a tupla devem corresponder aos tipos dos elementos em suas respectivas posições. Por exemplo, abaixo temos um exemplo incorreto de inicialização de tupla:
// Inicialização incorreta - os valores fornecidos não correspondem aos tipos nas posições
// userInfo = [28, "Tom"]; // Erro
Para acessar os elementos de uma tupla, assim como em um array, usamos índices:
let user: [string, number] = ["Tom", 36];
console.log(user[1]); // 36
user[1] = 37;
console.log(user[1]); // 37
Podemos iterar sobre os elementos de uma tupla usando um loop for
Tuplas em funções
Tuplas como parâmetros de função:
function printUser(user: [string, number]) {
console.log(user[0]);
console.log(user[1]);
}
let tom: [string, number] = ["Tom", 36];
printUser(tom);
Tupla como resultado de função:
function createUser(name: string, age: number): [string, number] {
return [name, age];
}
let user = createUser("Bob", 41);
console.log(user[0]);
console.log(user[1]);
Elementos opcionais em tuplas
Tuplas podem ter elementos opcionais, para os quais não é necessário fornecer um valor. Para indicar que um elemento é opcional, colocamos um ponto de interrogação ?
let bob: [string, number, boolean?] = ["Bob", 41, true];
let tom: [string, number, boolean?] = ["Tom", 36];
Nesse caso, o último elemento, que é do tipo boolean
Tupla com elementos opcionais como parâmetro de função:
function printUser(user: [string, number, boolean?]) {
if (user[2] !== undefined) {
console.log(`name: ${user[0]} age: ${user[1]} isMarried: ${user[2]}`);
} else {
console.log(`name: ${user[0]} age: ${user[1]}`);
}
}
let bob: [string, number, boolean] = ["Bob", 41, true];
let tom: [string, number] = ["Tom", 36];
printUser(bob);
printUser(tom);
É importante notar que a tupla tom aqui representa o tipo [string, number]
[string, number, boolean?]
Preenchendo tuplas
Usando o operador ...
let math: [string, ...number[]] = ["Math", 10, 9, 10, 9, 9];
let physics: [string, ...number[]] = ["Physics", 10, 10, 10];
Nesse caso, ambas as tuplas representam o tipo [string, ...number[]]
string
number
Tupla com quantidade indefinida de elementos como parâmetro de função:
function printMarks(marks: [string, ...number[]]) {
for (const mark of marks) {
console.log(mark);
}
}
let math: [string, ...number[]] = ["Math", 5, 4, 5, 4, 4];
let physics: [string, ...number[]] = ["Physics", 5, 5, 5];
printMarks(math);
printMarks(physics);
A quantidade indefinida de elementos pode ser definida no final, no meio ou no início da tupla:
let math: [string, ...number[]] = ["Math", 10, 4, 10, 9, 9];
let physics: [...number[], string] = [10, 10, 10, "Physics"];
let chemistry: [string, ...number[], boolean] = ["Chemistry", 8, 8, 9, 10, false];
No caso da tupla [...number[], string]
string
number
Na tupla do tipo [string, ...number[], boolean]
string
boolean
number
Tuplas somente leitura
Tuplas padrão permitem alterar os valores de seus elementos:
const tom: [string, number] = ["Tom", 36];
tom[1] = 37;
console.log(tom[1]); // 37
No entanto, o TypeScript também permite criar tuplas somente leitura, cujos elementos não podem ser alterados. Para isso, colocamos a palavra-chave readonly antes do tipo da tupla:
const tom: readonly [string, number] = ["Tom", 36];
tom[1] = 37; // ! Erro - não é possível alterar elementos de uma tupla somente leitura
Tupla somente leitura como parâmetro de função:
function printUser(user: readonly [string, number]) {
console.log(`name: ${user[0]} age: ${user[1]}`);
}
Tupla somente leitura como resultado de função:
function generateUser(): readonly [string, number] {
return ["Sam", 18];
}
Desestruturação de tupla
Assim como um array, uma tupla pode ser desestruturada em variáveis e constantes:
let tom: [string, number, boolean] = ["Tom", 36, false];
let [username, userage, isMarried] = tom; // desestruturação
console.log(username); // Tom
console.log(userage); // 36
console.log(isMarried); // false
Aqui, a tupla tom é desestruturada em três variáveis: username
userage
isMarried
Usando o operador ...
let tom: [string, number, boolean] = ["Tom", 36, false];
const [username, ...rest] = tom;
console.log(username); // Tom
console.log(rest[0]); // 36
console.log(rest[1]); // false
Aqui, a constante username recebe o primeiro elemento da tupla tom
"Tom"
rest
Podemos definir menos variáveis ou constantes do que elementos na tupla; nesse caso, os elementos restantes serão ignorados:
let tom: [string, number, boolean] = ["Tom", 36, false];
const [username, userage] = tom;
console.log(username); // Tom
console.log(userage); // 36
Também é possível deixar um espaço vazio no lugar de uma variável ou constante se quisermos pular o elemento correspondente da tupla:
let tom: [string, number, boolean, number] = ["Tom", 36, false, 170];
const [, age, , height] = tom; // pulamos o primeiro e o terceiro elementos
console.log(age); // 36
console.log(height); // 170