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.
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) { // ... }
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.
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:
T | undefined, il che viene considerato dal compilatore TypeScript e aiuta ad evitare errori.È 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.
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:
Contro:
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:
Contro: