ProgrammazioneSviluppatore Frontend

Come funziona il meccanismo di optional chaining in TypeScript? Quali problemi risolve e in quali casi il suo utilizzo può portare a errori nella pratica?

Supera i colloqui con l'assistente IA Hintsage

Risposta.

Il meccanismo di optional chaining (?.) è stato introdotto in JavaScript per facilitare l'accesso sicuro alle proprietà e ai metodi degli oggetti che potrebbero non essere definiti. In TypeScript è diventato particolarmente utile poiché aiuta a evitare errori di runtime legati all'accesso a proprietà o metodi undefined o null.

Storia della questione

Prima dell'introduzione dell'optional chaining, gli sviluppatori dovevano controllare manualmente l'esistenza di ogni livello di annidamento dell'oggetto, rendendo il codice lungo e difficilmente leggibile:

if (obj && obj.a && obj.a.b) { // ... }

Problema

Quando si accede a proprietà annidate di un oggetto non definito, si può verificare un errore di runtime: Cannot read property 'x' of undefined. Inoltre, lunghe catene di controlli rendono difficile la manutenzione e la comprensibilità del codice.

Soluzione

L'optional chaining (?.) permette di accedere a proprietà, metodi o elementi di un array annidati, restituendo automaticamente undefined se una qualsiasi parte della catena è null o undefined.

Esempio di codice:

interface User { name: string; address?: { city?: string; }; } const user: User = { name: 'Ivan' }; console.log(user.address?.city); // undefined

Caratteristiche chiave:

  • Permette di scrivere codice compatto, sicuro e chiaro.
  • Funziona con l'accesso a proprietà, metodi e indici di array.
  • Il tipo di valore restituito è T | undefined, il che viene considerato dal compilatore TypeScript e aiuta ad evitare errori.

Domande trabocchetto.

È possibile utilizzare l'optional chaining a sinistra dell'operatore di assegnazione? Ad esempio: user.address?.city = 'Moscow'?

No, l'optional chaining non può essere utilizzato nell'espressione di sinistra di un'assegnazione, questo genererà un errore di compilazione. L'optional chaining funziona solo in lettura, non in scrittura.

È possibile utilizzare l'optional chaining per chiamare un metodo se l'oggetto stesso potrebbe non essere definito? Ad esempio: user?.logInfo()?

Sì, se l'oggetto prima del punto di chiamata del metodo può essere undefined/null, allora la chiamata user?.logInfo() non genererà un errore e restituirà semplicemente undefined se user non è definito.

user?.logInfo(); // se user è definito, verrà chiamato logInfo, altrimenti non succederà nulla

Qual è la differenza tra optional chaining e l'operatore '&&' nel vecchio stile, ad esempio: user && user.address && user.address.city?

L'optional chaining è più conciso, funziona per tutti i tipi (inclusi metodi e array), e TypeScript lo considera nella verifica dei tipi. È importante notare che quando si utilizza l'operatore '&&' è possibile ottenere per caso un valore annidato anziché true/false o undefined. L'optional chaining, invece, garantisce di restituire sempre il tipo previsto o undefined, il che è considerato dal sistema di inferenza dei tipi.

Errori comuni e anti-pattern

  • Aspettarsi che l'optional chaining "crei" oggetti annidati durante le assegnazioni — non è così.
  • Utilizzare l'optional chaining per accedere a variabili che per tipo non possono mai essere undefined/null (codice superfluo e inutile).
  • L'abitudine di applicare l'optional chaining senza riflessione in ogni luogo, il che complica ulteriormente la manutenzione del codice.

Esempio dalla vita reale

Caso negativo

Nel codice vengono utilizzate lunghe catene di optional chaining anche lì dove le variabili, per logica di business, sono sempre definite:

order?.customer?.address?.city = 'London';

Pro:

  • Protegge da possibili errori, nel caso in cui le proprietà risultino effettivamente non definite.

Contro:

  • La assegnazione non avverrà se anche una sola delle proprietà è assente, non c'è notifica o gestione dell'errore; si crea una logica "nascosta", confusione del codice.

Caso positivo

Si utilizza l'optional chaining solo quando si lavora con dati esterni o in luoghi dove i valori possono davvero essere indefiniti:

const city = apiResponse?.info?.location?.city || 'Unknown';

Pro:

  • Funziona in modo sicuro anche con oggetti incompleti o inaspettatamente modificati senza lanci di eccezioni.
  • Codice facile da leggere e mantenere.

Contro:

  • Se è necessario sapere perché un valore è assente, è necessario implementare una gestione esplicita degli errori.