Dans la partie précédente de cette série d'articles, nous avons discuté de la nullité sécurisée.
Nous allons maintenant expliquer et résoudre le troisième et dernier problème du comportement par défaut de TypeScript : reste du typage dynamique.
Nous couvrirons :
TypeScript est censé être un "vérificateur de type statique", par opposition à JavaScript dans lequel la saisie est profondément dynamique.
Mais dans une partie précédente de cette série d'articles, nous avons également expliqué que TypeScript est construit comme un sur-ensemble de JavaScript.
Le problème est donc le suivant : certaines parties du système de typage dynamique JavaScript restent dans TypeScript. Nous allons donc expliquer comment supprimer ces comportements restants pour obtenir un typage statique complet.
Le meilleur exemple du problème est celui des contrôles d'égalité. En JavaScript, == n'est pas exactement une vérification d'égalité, mais une vérification d'équivalence :
1 == "1"; // true
Bien que les types soient différents, certaines règles de conversion entrent en action afin que JavaScript soit capable de comparer les valeurs. Cela peut conduire à beaucoup d'erreurs, car les détails des règles sont difficiles à retenir, sont parfois assez bizarres, et ne sont pas exactement les mêmes dans tous les langages dynamiques (comme PHP par exemple).
Ces vérifications d'équivalence n'ont de sens que dans un langage typé dynamiquement comme JavaScript. À partir du moment où nous décidons de travailler en TypeScript, seules les vérifications d'égalité réelles (type et valeur) doivent être utilisées.
1 === "1"; // false
La règle eqeqeq lint l'applique.
Les personnes venant de langages comme Java, C# ou Rust doivent être particulièrement prudentes avec ce problème, car == en JavaScript ou TypeScript ne signifie pas la même chose que dans ces langages. En JavaScript et TypeScript, un troisième = est requis pour obtenir le même comportement.
Vous pensez que les conditions sont désormais sûres ? Malheureusement non, car les conversions peuvent être implicites :
let tax: number | undefined = 0; if (tax) { console.log("Process payment"); } if (!tax) { throw new Error(); }
L'exemple ci-dessus est équivalent à :
let tax: number | undefined = 0; if (tax == true) { console.log("Process payment"); } if (tax == false) { throw new Error(); }
Comme vous pouvez le voir, il y avait des == implicites, donc les conversions se produisent toujours : 0 n'est pas équivalent à vrai, c'est équivalent à faux. Il y aura donc une erreur même si la taxe est une valeur valide.
La règle lint stricte-boolean-expressions interdit de telles conditions implicites et applique des contrôles réels :
let tax: number | undefined = 0; if (tax !== undefined) { console.log("Process payment"); } if (tax === undefined) { throw new Error(); }
C'est peut-être l'une des règles les plus fastidieuses à suivre pour les personnes habituées aux conditions rapides en JavaScript, mais pour mettre les choses en perspective, c'est simplement la façon normale de faire les choses dans d'autres langages comme Java, C# ou Rust.
Comme indiqué dans la partie configuration, il est important de désactiver les sous-options AllowNumber et AllowString pour éviter toutes les erreurs.
La seule exception autorisée concerne les objets et les tableaux : ces cas sont sûrs car contrairement aux chaînes et aux nombres, ils n'ont pas de valeurs fausses. Donc ce qui suit est toujours OK :
let movie: Movie | undefined; if (movie) {} if (!movie) {}
Remarque : les instructions switch sont déjà sûres car elles utilisent === en interne.
La règle lint stricte-boolean-expressions veille à ce que les vérifications de conditions soient de type sécurisé, mais il existe d'autres syntaxes de conditions que if :
const movieRating = userRating || 5; // Which is a shorter version of: const movieRating = userRating == true ? userRating : 5;
Si l'utilisateur a noté 0, 0 équivaut à faux, donc la note sera de 5 au lieu de 0.
Cela peut être évité avec du JavaScript moderne :
const movieRating = userRating ?? 5; // Which is a shorter version of: const movieRating = userRating !== undefined && userRating !== null ? userRating : 5;
Il peut être appliqué par la règle des charpies préférentielles-nullish-coalescing.
Noter que ?? ne doit pas être utilisé partout : || est toujours pertinent lorsque vous travaillez avec des booléens.
En JavaScript, l'opérateur peut être utilisé à la fois pour l'addition mathématique de nombres ou pour la concaténation de chaînes. Cela conduit à une erreur.
"There is " 3 1 "Matrix movies"; // 31 "There is " (3 1) "Matrix movies"; // 4
L'opérateur doit être réservé à l'addition mathématique. Ou du moins, il ne doit être utilisé qu'avec des données du même type, ce que la règle de restriction plus opérandes lint applique.
Les chaînes de modèle du JavaScript moderne doivent être utilisées pour la concaténation de chaînes, ce que la règle de lint préfère-modèle applique :
const movie = `Everything everywhere all at once`; `${movie} is the best movie!`;
À l'inverse, seules les chaînes doivent être utilisées dans les chaînes de modèle, ce que la règle de lint restrict-template-expressions applique.
Si le mélange des types est réellement souhaité, les conversions doivent être explicites :
const total = 3; `There is ${total.toFixed()} Matrix movies`;
Notez que les chaînes de modèles peuvent être imbriquées :
const total = 3; `There is ${total.toFixed()} Matrix movie${total > 1 ? "s" : ""}`;
C'est la fin de cette série d'articles. Vous pouvez suivre mon compte (bouton en haut à droite de cette page) pour savoir quand d'autres articles sur TypeScript ou d'autres sujets comme Angular sont publiés.
Vous souhaitez me contacter ? Les instructions sont disponibles dans le résumé.
Clause de non-responsabilité: Toutes les ressources fournies proviennent en partie d'Internet. En cas de violation de vos droits d'auteur ou d'autres droits et intérêts, veuillez expliquer les raisons détaillées et fournir une preuve du droit d'auteur ou des droits et intérêts, puis l'envoyer à l'adresse e-mail : [email protected]. Nous nous en occuperons pour vous dans les plus brefs délais.
Copyright© 2022 湘ICP备2022001581号-3