"Si un ouvrier veut bien faire son travail, il doit d'abord affûter ses outils." - Confucius, "Les Entretiens de Confucius. Lu Linggong"
Page de garde > La programmation > TypeScript strictement typé - Types statiques complets en partie

TypeScript strictement typé - Types statiques complets en partie

Publié le 2024-08-06
Parcourir:484

TypeScript strictly typed - Part full static types

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 :

  • Restes de typage dynamique
  • Contrôles d'égalité réels
  • Aucune conversion implicite dans les conditions
  • Notation abrégée des conditions
  • Aucun mélange de chaînes et de chiffres

Restes de typage dynamique

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.

Contrôles d'égalité réels

  • ESLint : eqeqeq
  • Biome : suspect.noDoubleEquals (en recommandé)

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.

Aucune conversion implicite dans les conditions

  • ESLint : @typescript-eslint/strict-boolean-expressions
  • Biome : règle manquante

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.

Notation abrégée des conditions

  • ESLint : @typescript-eslint/prefer-nullish-coalescing (en style-type-checked)
  • Biome : règle manquante

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.

Pas de mélange de chaînes et de chiffres

  • ESLint :
    • préférer le modèle
    • @typescript-eslint/restrict-plus-operands (en type recommandé-vérifié)
    • @typescript-eslint/restrict-template-expressions (en type recommandé-vérifié)
  • Biome :
    • style.useTemplate (en recommandé)
    • autres règles manquantes

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" : ""}`;

Conclusion

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é.

Déclaration de sortie Cet article est reproduit sur : https://dev.to/cyrilletuzi/typescript-strictly-typed-part-4-full-static-types-8bc?1 En cas de violation, veuillez contacter [email protected] pour supprimer il
Dernier tutoriel Plus>

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