ProgrammationDéveloppeur Frontend

Comment fonctionne le mécanisme de chaînage optionnel (optional chaining) en TypeScript ? Quels problèmes résout-il et dans quels cas son utilisation peut-elle conduire à des erreurs en pratique ?

Réussissez les entretiens avec l'assistant IA Hintsage

Réponse.

Le mécanisme de chaînage optionnel (?.) est apparu en JavaScript pour un accès sûr et pratique aux propriétés et méthodes des objets qui peuvent ne pas être définis. En TypeScript, il est particulièrement utile car il aide à éviter les erreurs d'exécution liées à l'accès aux propriétés ou méthodes de undefined ou null.

Historique du problème

Avant l'apparition du chaînage optionnel, les développeurs devaient vérifier manuellement l'existence de chaque niveau d'imbrication d'un objet, ce qui rendait le code long et difficile à lire :

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

Problème

Lors de l'accès aux propriétés imbriquées d'un objet indéfini, une erreur d'exécution peut survenir : Cannot read property 'x' of undefined. De plus, de longues chaînes de vérifications compliquent la maintenance et la lisibilité du code.

Solution

Le chaînage optionnel (?.) permet d'accéder aux propriétés imbriquées, méthodes ou éléments de tableau, en retournant automatiquement undefined si une partie de la chaîne est null ou undefined.

Exemple de code :

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

Caractéristiques clés :

  • Permet d'écrire du code compact, sûr et compréhensible.
  • Fonctionne avec l'accès aux propriétés, méthodes et index des tableaux.
  • Le type de valeur retournée est T | undefined, ce qui est pris en compte par le compilateur TypeScript et aide à éviter les erreurs.

Questions pièges.

Peut-on utiliser le chaînage optionnel à gauche de l'opérateur d'affectation ? Par exemple : user.address?.city = 'Moscow' ?

Non, le chaînage optionnel ne peut pas être utilisé dans l'expression de gauche d'une affectation, cela provoquera une erreur de compilation. Le chaînage optionnel ne fonctionne que lors de la lecture, et non lors de l'écriture.

Peut-on utiliser le chaînage optionnel pour appeler une méthode si l'objet lui-même peut ne pas être défini ? Par exemple : user?.logInfo() ?

Oui, si l'objet avant le point d'appel de la méthode peut être indéfini/null, alors l'appel user?.logInfo() ne lancera pas d'erreur et retournera simplement undefined si user n'est pas défini.

user?.logInfo(); // si user est défini, logInfo sera appelé, sinon rien ne se passera

Quelle est la différence entre le chaînage optionnel et l'opérateur '&&' à l'ancienne, par exemple : user && user.address && user.address.city ?

Le chaînage optionnel est plus court, fonctionne pour tous les types (y compris les méthodes et les tableaux), et TypeScript le prend en compte lors de la vérification des types. Il est important qu'en utilisant l'opérateur '&&', vous pouvez accidentellement obtenir une valeur imbriquée qui n'est pas true/false ou undefined. Le chaînage optionnel garantit de retourner soit le type attendu, soit undefined, ce qui est pris en compte dans l'inférence des types.

Erreurs typiques et anti-patrons

  • Attendre que le chaînage optionnel "crée" des objets imbriqués lors de l'affectation — ce n'est pas le cas.
  • Utiliser le chaînage optionnel pour accéder à des variables qui ne peuvent jamais être undefined/null par type (code superflu et inutile).
  • L'habitude d'appliquer sans discernement le chaînage optionnel partout, ce qui complique la maintenance future du code.

Exemple de la vie réelle

Cas négatif

Dans le code, de longues chaînes de chaînage optionnel sont utilisées même lorsque les variables sont toujours définies selon la logique métier :

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

Avantages :

  • Protège contre d'éventuelles erreurs, si les propriétés s'avèrent non définies.

Inconvénients :

  • L'affectation ne se produira pas si l'une des propriétés est absente, sans notification ou traitement d'erreur ; une logique "cachée" apparaît, rendant le code confus.

Cas positif

Le chaînage optionnel est utilisé uniquement lors du travail avec des données externes ou dans des cas où les valeurs peuvent vraiment être indéfinies :

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

Avantages :

  • Fonctionne en toute sécurité même avec des objets incomplets ou ayant changé de manière inattendue sans déclencher d'exceptions.
  • Code simple à lire et à maintenir.

Inconvénients :

  • Si vous devez savoir pourquoi la valeur est absente, vous devez faire un traitement explicite des erreurs.