TypeScript permette di descrivere con precisione i tipi utilizzati dal programma, ma può capitare di lavorare con valori di cui non conosciamo il tipo in anticipo.
In queste situazioni esistono due tipi particolarmente importanti: any e unknown.
A prima vista possono sembrare simili, perché entrambi permettono di assegnare valori di tipi diversi. Il loro comportamento, però, è molto diverso:
any disattiva sostanzialmente i controlli di tipo per quel valore.unknown mantiene la sicurezza dei tipi e richiede di verificare il tipo prima di utilizzare il valore.Il tipo any indica che una variabile può contenere un valore di qualsiasi tipo.
Ad esempio:
let valore: any = "Andrea";
valore = 10;
valore = true;Tutte queste assegnazioni sono valide perché any permette di utilizzare il valore senza applicare i normali controlli di TypeScript.
Possiamo anche eseguire operazioni che normalmente richiederebbero un determinato tipo:
let valore: any = "Andrea";
valore.toUpperCase();Uno dei principali vantaggi di TypeScript è la type-safety, cioè la possibilità di individuare molti errori legati ai tipi prima dell'esecuzione.
Utilizzando any, questo controllo viene sostanzialmente disattivato per il valore interessato.
Ad esempio:
let valore: any = "ciao";
valore.metodo();TypeScript non può verificare se metodo() sia realmente un metodo disponibile sul valore. Se il codice viene eseguito, potrebbe quindi verificarsi un errore.
Per questo motivo, un uso eccessivo di any può rendere un progetto TypeScript molto simile a un progetto JavaScript non tipizzato.
Per una maggiore sicurezza rispetto ad any, TypeScript mette a disposizione il tipo unknown.
Anche unknown permette di assegnare valori di qualsiasi tipo:
let valore: unknown = "Andrea";
valore = 10;
valore = true;Fin qui il comportamento sembra simile a any.
La differenza fondamentale emerge quando proviamo a utilizzare il valore. Con any possiamo scrivere:
let valore: any = "Andrea";
valore.toUpperCase();Con unknown, invece, viene segnalato un errore:
let valore: unknown = "Andrea";
valore.toUpperCase(); // ErroreIl motivo è semplice: anche se sappiamo che inizialmente abbiamo assegnato una stringa, il tipo dichiarato è unknown, quindi TypeScript deve considerare possibile che il valore possa essere di qualsiasi tipo.
Prima di utilizzare il valore dobbiamo quindi controllarne il tipo.
Uno dei modi più semplici per verificare un valore unknown consiste nell'utilizzare typeof. Ad esempio:
let valore: unknown = "Andrea";
if (typeof valore === "string") {
console.log(valore.toUpperCase());
}All'interno del blocco if, TypeScript sa che valore è una stringa. Possiamo quindi utilizzare i metodi disponibili per string.
Possiamo fare la stessa cosa con altri tipi:
let valore: unknown = 10;
if (typeof valore === "number") {
console.log(valore.toFixed(2));
}Il controllo typeof valore === "number" permette a TypeScript di sapere che, all'interno di quel blocco, il valore è un number.