Maison  >  Article  >  interface Web  >  TypeScript strictement typé - Types statiques complets en partie

TypeScript strictement typé - Types statiques complets en partie

王林
王林original
2024-08-01 01:51:22820parcourir

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 :

  • Reste de la saisie dynamique
  • Contrôles d'égalité réels
  • Aucune conversion implicite dans les conditions
  • Notation abrégée des conditions
  • Pas de 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 ont toujours lieu : 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 juste 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 strict-boolean-expressions lint 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 nulles.

Notez que ?? ne doit pas être utilisé partout : || est toujours pertinent lorsque l'on travaille 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.

Template strings from modern JavaScript should be used for string concatenation, which the prefer-template lint rule enforces:

const movie = `Everything everywhere all at once`;
`${movie} is the best movie!`;

Conversely, only strings should be used in template strings, which the restrict-template-expressions lint rule enforces.

If mixing types is what is actually wanted, conversions should be explicit:

const total = 3;
`There is ${total.toFixed()} Matrix movies`;

Note that template strings can be nested:

const total = 3;
`There is ${total.toFixed()} Matrix movie${total > 1 ? "s" : ""}`;

Conclusion

This is the end of this posts series. You can follow my account (button on top right of this page) to know when other posts about TypeScript or other topics like Angular are published.

You want to contact me? Instructions are available in the summary.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Article précédent:Qu'est-ce que NodejsArticle suivant:Qu'est-ce que Nodejs