Le tuple in TypeScript

In TypeScript, una tupla è una struttura simile a un array, ma con una differenza fondamentale: permette di stabilire quanti elementi deve contenere e quale tipo deve avere ciascuna posizione.

Per esempio, possiamo definire una tupla che contiene una stringa nella prima posizione e un numero nella seconda:

const persona: [string, number] = ["Andrea", 30];

In questo caso TypeScript conosce non soltanto i tipi degli elementi, ma anche la loro posizione: persona[0] è di tipo string, mentre persona[1] è di tipo number.

Come definire una tupla

Le tuple sono particolarmente utili quando ogni posizione di un array ha un significato preciso, perché permettono di definire in modo più preciso la struttura e i tipi dei dati contenuti.

La sintassi di una tupla è: [tipo1,tipo2,tipo3, ...].

Ad esempio, possiamo definire la tupla persona:

const persona: [string, number] = ["Andrea", 30];

La prima posizione deve contenere una string, mentre la seconda deve contenere un number.

Ad esempio, questa tupla genera un errore:

const persona: [string, number] = [30, "Andrea"];

Nell'esempio, i tipi sono nell'ordine sbagliato.

Gestire i dati nelle tuple

In una tupla in TypeScript, è possibile accedere agli elementi e modificarli.

Accedere agli elementi

Quando accediamo a una posizione specifica di una tupla, TypeScript conosce il tipo previsto per quella posizione.

Consideriamo questo esempio:

const persona: [string, number] = ["Andrea", 30];

Possiamo accedere al primo elemento in questo modo:

const nome = persona[0];

Nell'esempio, TypeScript sa che nome è di tipo string.

Modificare gli elementi

Possiamo modificare gli elementi di una tupla, rispettando però i tipi definiti per ciascuna posizione.

Per esempio:

let persona: [string, number] = ["Andrea", 30];

persona[0] = "Luca";
persona[1] = 25;

Entrambe le operazioni di assegnazione dei valori sono valide.

Non possiamo invece assegnare un numero alla prima posizione, oppure una stringa alla seconda. In questo caso, TypeScript segnala un errore perché la struttura della tupla stabilisce il tipo di ogni posizione.

Aggiungere elementi

Anche se una tupla definisce una struttura precisa, rimane comunque un tipo di array. Questo significa che possiamo utilizzare diversi metodi degli array.

Ad esempio, possiamo usare push():

let persona: [string, number] = ["Andrea", 30];

persona.push("Italia");

Questo comportamento può sembrare sorprendente: abbiamo definito una tupla con due elementi, ma push() permette di aggiungerne un terzo.

È importante quindi sapere che la lunghezza e i tipi definiti dalla tupla non impediscono completamente le modifiche attraverso i metodi degli array.

Dopo l'esecuzione del codice nell'esempio, la struttura effettiva può quindi contenere:

["Andrea", 30, 40]

Questo comportamento, anche se può sembrare strano, è dovuto al fatto che le tuple in TypeScript sono un tipo di array e possono quindi utilizzare i metodi degli array, incluso push().

Elementi opzionali nelle tuple

Possiamo rendere opzionale un elemento della tupla utilizzando ? dopo il tipo.

Ad esempio:

const persona: [string, number?] = ["Andrea"];

Nell'esempio, la prima posizione è obbligatoria, mentre la seconda è facoltativa.

Possiamo quindi creare entrambe queste tuple:

const persona1: [string, number?] = ["Marco"];

const persona2: [string, number?] = ["Marco", 30];

La seconda posizione, quando presente, deve comunque essere un number.

Nota: gli elementi opzionali devono trovarsi alla fine della tupla. Ad esempio, questo codice genera un errore, perché un elemento opzionale non può precedere un elemento obbligatorio:

const persona: [string?, number] = [30];
È possibile, però, avere più elementi opzionali consecutivi.

Tuple immutabili

Possiamo dichiarare una tupla come readonly. In questo caso non possiamo modificare direttamente gli elementi. Ad esempio:

const persona: readonly [string, number] = ["Andrea", 30];

persona[0] = "Luca"; // Errore
persona.push(40); // Errore

La proprietà readonly permette di mantenere più facilmente la struttura della tupla invariata.

Prova!Completa gli spazi vuoti con il testo appropriato.
// Rimuovi l'ultimo elemento della tupla
const punto: [number, number?] = [5, 10, 15];

punto.();

Prova! Scegli l'opzione corretta tra quelle elencate.
// Rendi la tupla immutabile
const coordinate: ______ [number, number] = [10, 20];

coordinate[0] = 15; // Errore