Perché 'as' in TypeScript è spesso pericoloso?
Usi TypeScript per la sicurezza che porta al tuo codice, ma avrai sicuramente notato che l'operatore as
permette di forzare la compilazione anche quando TypeScript sospetta tipi incompatibili. Questa flessibilità può essere allettante, ma spesso nasconde delle trappole. Scopriamo insieme perché l'uso eccessivo di as
può introdurre errori di runtime e come evitare queste insidie.
Il problema di as
: errori nascosti durante la compilazione
In TypeScript, l'operatore as
permette di fare quello che chiamiamo type assertion, ovvero dire a TypeScript "Fidati di me, so quello che sto facendo." Tuttavia, questo strumento può talvolta essere una cattiva idea, perché aggira i controlli dei tipi. Quando usi as
, ti assumi la responsabilità di garantire che il tipo sia effettivamente corretto, anche se TypeScript non può verificarlo. Vediamo questo con alcuni esempi concreti.
Esempio 1: Forzare un tipo con as
che non è realmente compatibile
Prendiamo un esempio dove hai un oggetto di tipo Person
con alcune proprietà ben definite, ma decidi di usare as
per forzarlo a un tipo diverso, pensando che funzionerà.
typescript
In questo esempio, employee
non ha la proprietà role
, ma TypeScript non restituisce un errore durante la compilazione grazie a as
. Tuttavia, durante l'esecuzione, employee.role
è undefined
, il che può causare errori se il tuo codice si aspetta un valore di tipo string
.
Esempio 2: Ignorare i controlli con as unknown as
A volte, vediamo gli sviluppatori utilizzare casting a catena per forzare un tipo tramite unknown
, come in questo esempio:
typescript
Qui, prendiamo un valore data
che potrebbe essere qualsiasi cosa e lo castiamo in number
tramite unknown
. Durante la compilazione, tutto sembra funzionare, ma durante l'esecuzione, l'addizione produce NaN
perché data
era in realtà una stringa.
Esempio 3: Manipolare oggetti parziali
Prendiamo un altro caso classico dove forziamo un oggetto parzialmente completato a un tipo completo pensando che andrà tutto bene:
typescript
L'oggetto partialProduct
viene convertito in Product
anche se manca la proprietà price
. Questa assenza non viene rilevata da TypeScript grazie a as
, ma porta a un undefined
che può generare errori di runtime se questo valore viene utilizzato senza una verifica preliminare.
Come evitare gli errori con Zod
Per evitare i problemi generati da as
, una buona pratica è validare i dati durante l'esecuzione, in particolare se provengono da una fonte esterna. È qui che entra in gioco Zod. Zod è una libreria di validazione degli schemi in TypeScript che permette di definire tipi sicuri e validarli a runtime.
Con Zod, invece di forzare un tipo con as
, puoi validare e convertire i dati con uno schema predefinito. Per esempio:
typescript
In questo esempio, Zod verifica che partialProduct
rispetti effettivamente lo schema Product
. Se mancano delle proprietà, Zod restituisce un errore di validazione invece di lasciare passare valori undefined
. Grazie a Zod, metti in sicurezza i tuoi dati ed eviti errori di runtime legati a tipi incompleti o incorretti.
Conclusione
L'operatore as
può essere una soluzione rapida per aggirare i controlli di TypeScript, ma introduce rischi di errori di runtime, soprattutto quando si forzano tipi senza validazione. Utilizzando una libreria come Zod, puoi validare i tuoi dati a runtime e così sfruttare pienamente la sicurezza di TypeScript, anche nei casi in cui as
sembrava l'unica soluzione.