Introduction : la question qui tourmente les débutants
\nAvez-vous déjà écrit du code en TypeScript et obtenu une erreur comme Cannot read property 'name' of undefined ? Une douleur familière, n'est-ce pas ? Surtout lorsque vous travaillez avec des données provenant d'un serveur ou avec des objets profondément imbriqués. C'est précisément dans ces moments que l'on se demande : « Existe-t-il en TypeScript un opérateur qui permet d'accéder aux propriétés en toute sécurité, sans craindre que tout ne s'effondre ? »
Sur Stack Overflow, cette question a recueilli des milliers de vues. Et la réponse est oui, un tel opérateur existe. De plus, il existe aussi en JavaScript (depuis ES2020), et en TypeScript, il fonctionne « nativement ». Il s'appelle optional chaining (chaînage optionnel), et il ressemble au familier ?.. Dans cet article, nous ne nous contenterons pas de vous expliquer comment l'utiliser, mais nous regarderons également sous le capot : comment le compilateur TypeScript transforme cette syntaxe élégante en code JavaScript sécurisé.
Comment s'appelle l'opérateur ?. en TypeScript ?
\nCommençons par l'essentiel. Dans la communauté des développeurs, cet opérateur est appelé de différentes manières :
\n- \n
- Optional chaining (chaînage optionnel) — le nom officiel dans la spécification ECMAScript. \n
- Opérateur d'accès sécurisé (Safe navigation operator) — vient d'autres langages, comme C# et Swift. \n
- Opérateur conditionnel null (Null-conditional operator) — présent dans la documentation Microsoft. \n
Mais le principe est le même : ?. permet d'accéder à une propriété d'un objet, et si l'objet est null ou undefined, au lieu d'une erreur, on obtient simplement undefined. Ce n'est pas de la magie, mais simplement du sucre syntaxique qui rend le code plus propre et plus sûr.
Syntaxe de base
\nLa syntaxe est extrêmement simple. Au lieu d'écrire :
\nif (user && user.profile && user.profile.name) {\n console.log(user.profile.name);\n}\nVous écrivez :
\nconsole.log(user?.profile?.name);\nSi user est undefined, toute la chaîne est interrompue et undefined est affiché dans la console. Pas d'erreurs, pas de vérifications superflues. Magnifique !
Comment cela fonctionne sous le capot : compilation de TypeScript en JavaScript
\nTypeScript est une surcouche de JavaScript. Il n'exécute pas le code directement, mais le compile en JS standard. Voyons donc ce que devient notre élégant user?.profile?.name après compilation.
Exemple : chaînage optionnel simple
\nCode source en TypeScript :
\nconst name = user?.profile?.name;\nAprès compilation (cible ES5) :
\nvar name = user === null || user === void 0 ? void 0 : user.profile === null || user.profile === void 0 ? void 0 : user.profile.name;\nQue se passe-t-il ici ? Le compilateur génère un opérateur ternaire qui vérifie chaque niveau d'imbrication pour null ou undefined. Si la valeur est null ou undefined, il retourne void 0 (c'est simplement un moyen fiable d'obtenir undefined sur les anciens moteurs). Sinon, on continue. En substance, c'est exactement le code « manuel » que nous écrivions auparavant, mais désormais généré par la machine.
Exemple : chaînage optionnel avec appel de fonction
\nL'opérateur ?. ne fonctionne pas seulement avec les propriétés, mais aussi avec les appels de fonctions. Supposons que nous ayons une méthode getAddress qui peut être absente :
const address = user?.getAddress?.();\nAprès compilation :
\nvar address = user === null || user === void 0 ? void 0 : (typeof user.getAddress === "function" ? user.getAddress() : void 0);\nRemarquez : le compilateur ne se contente pas de vérifier null, il s'assure également que getAddress est bien une fonction avant de l'appeler. Si ce n'est pas une fonction, il retourne undef