Maison > interface Web > tutoriel CSS > Démystifier les syndicats de dactylographie discriminés

Démystifier les syndicats de dactylographie discriminés

Joseph Gordon-Levitt
Libérer: 2025-03-14 10:57:09
original
960 Les gens l'ont consulté

Démystifier les syndicats de dactylographie discriminés

TypeScript est un outil puissant pour construire des applications JavaScript évolutives et est presque devenu la norme pour les grands projets JavaScript Web. Cependant, pour les débutants, TypeScript a également des choses délicates, dont l'une se distingue entre les types d'union.

Considérez le code suivant:

 interface chat {
  Poids: numéro;
  Whiskers: numéro;
}
chien d'interface {
  Poids: numéro;
  Friendly: booléen;
}
Laissez l'animal: chien | Cat;
Copier après la connexion
Copier après la connexion

De nombreux développeurs seront surpris de constater que lors de l'accès animal , seul weight est valide, tandis que whiskers et les attributs friendly ne sont pas valides. Cet article expliquera les raisons.

Avant de plonger, passons rapidement en revue les types structurels et nominaux, ce qui aidera à comprendre la distinction de TypeScript entre les types d'union.

Type de structure

La meilleure façon de comprendre les types structurels est de les comparer avec des types nominaux. La plupart des langues dactylographiées que vous pourriez avoir utilisées sont tapées nominalement. Par exemple, C # Code (Java ou C similaire):

 classe foo {
  public int x;
}
classe Blah {
  public int x;
}
Copier après la connexion

Même si Foo et Blah ont exactement la même structure, ils ne peuvent pas s'attribuer des valeurs les uns aux autres. Le code suivant:

 Blah b = new foo ();
Copier après la connexion

L'erreur suivante sera générée:

<code>无法隐式转换类型“Foo”为“Blah”</code>
Copier après la connexion

La structure de ces classes n'a pas d'importance. Une variable de type Foo ne peut être attribuée qu'à une instance de Foo (ou de sa sous-classe).

TypeScript, au contraire, adopte les types de structure. TypeScript les considère comme compatibles si les deux types ont la même structure.

Par conséquent, le code suivant fonctionne bien:

 classe foo {
  x: nombre = 0;
}
classe Blah {
  x: nombre = 0;
}
Soit f: foo = new Blah ();
Soit b: blah = new foo ();
Copier après la connexion

Une collection de types comme valeurs correspondantes

Expliquons cela plus loin. Compte tenu du code suivant:

 classe foo {
  x: nombre = 0;
}

Soit f: foo;
Copier après la connexion

f est une variable qui peut contenir n'importe quel objet qui est la même structure que Foo , dans ce cas, ce qui signifie une propriété x représentant un nombre. Cela signifie que même un objet JavaScript normal peut être accepté.

 Soit f: foo;
f = {
  x: 0
};
Copier après la connexion

Type d'union

Revenons au code au début de cet article:

 interface chat {
  Poids: numéro;
  Whiskers: numéro;
}
chien d'interface {
  Poids: numéro;
  Friendly: booléen;
}
Copier après la connexion

Nous savons:

 Laissez l'animal: chien;
Copier après la connexion

Faites animal n'importe quel objet avec la même structure que l'interface Dog . Alors, que signifie le code suivant?

 Laissez l'animal: chien | Cat;
Copier après la connexion
Copier après la connexion
Copier après la connexion

Cela définit le type d' animal comme n'importe quel objet qui correspond à l'interface Dog , ou tout objet qui correspond à l'interface Cat .

Alors pourquoi animal nous permet-il maintenant d'accéder weight ? Autrement dit, c'est parce que TypeScript ne sait pas de quel type il s'agit. TypeScript sait animal doit être Dog ou Cat , mais cela peut être l'un ou l'autre. Si nous sommes autorisés à accéder à la propriété friendly , mais qu'en cas animal est en fait Cat et non Dog , cela peut entraîner une erreur d'exécution. Il en va de même pour whiskers .

Le type d'union est une union de valeurs valides, et non une union d'attributs. Les développeurs écrivent souvent du code comme ceci:

 Laissez l'animal: chien | Cat;
Copier après la connexion
Copier après la connexion
Copier après la connexion

Et attendez-vous à ce que animal aient une union de propriétés Dog et Cat . Mais c'est une autre erreur. Cela spécifie animal a une valeur qui correspond à une articulation de valeurs Cat Dog valides et valides. Mais TypeScript vous permet uniquement d'accéder aux propriétés qu'il sait . Actuellement, cela signifie tous les types de propriétés de l'Union.

Type de type

Maintenant, nous avons:

 Laissez l'animal: chien | Cat;
Copier après la connexion
Copier après la connexion
Copier après la connexion

Lorsque animal est Dog , comment le traitons-nous correctement comme des propriétés Dog et d'accès sur l'interface Dog , et aussi la gérer quand c'est Cat ? Actuellement, nous pouvons utiliser l'opérateur in . Il s'agit d'un ancien opérateur JavaScript que vous ne voyez peut-être pas très souvent, ce qui nous permet de tester si une propriété existe dans un objet. Par exemple:

 Soit O = {A: 12};

"A" en o;
"x" dans o; // faux
Copier après la connexion

Il s'avère que TypeScript est profondément intégré à l'opérateur in . Voyons comment utiliser:

 Laissez l'animal: chien | Cat = {} comme n'importe quel autre;

if ("amical" en animal) {
  console.log (animal.friendly);
} autre {
  console.log (animal.whiskers);
}
Copier après la connexion

Ce code ne produira pas d'erreurs. Dans le bloc if , TypeScript sait qu'il y a une propriété friendly , alors convertit animal en Dog . Dans le bloc else , TypeScript traite de la même manière animal comme Cat . Vous pouvez même afficher cela dans l'éditeur de code en survolant votre souris sur un objet animal dans ces blocs.

Distinguer les types d'union

Vous pourriez vous attendre à ce que le billet de blog se termine ici, mais malheureusement, le rétrécissement du type syndical est très limité en vérifiant si l'attribut existe. Cela fonctionne bien pour nos types Dog et Cat simples, mais lorsque nous avons plus de types et plus de chevauchement entre ces types, les choses peuvent facilement devenir plus complexes et fragiles.

C'est là que la différenciation du type syndical est utile. Nous allons tout garder d'avant, il suffit d'ajouter une propriété à chaque type, dont le seul but est de distinguer (ou de "différencier" ces types:

 interface chat {
  Poids: numéro;
  Whiskers: numéro;
  Animal_type: "Cat";
}
chien d'interface {
  Poids: numéro;
  Friendly: booléen;
  Animal_type: "chien";
}
Copier après la connexion

Notez l'attribut ANIMAL_TYPE sur les deux types. Ne le confondez pas avec une chaîne avec deux valeurs différentes; ANIMAL_TYPE: "CAT";

Maintenant, notre inspection est devenue plus fiable:

 Laissez l'animal: chien | Cat = {} comme n'importe quel autre;

if (animal.animal_type === "chien") {
  console.log (animal.friendly);
} autre {
  console.log (animal.whiskers);
}
Copier après la connexion

Ce chèque sera infaillible en supposant que chaque type participant à l'Union a une valeur différente de l'attribut ANIMAL_TYPE .

Le seul inconvénient est que vous devez maintenant faire face à une nouvelle propriété. Chaque fois qu'une instance de Dog ou Cat est créée, vous devez fournir la valeur correcte unique pour ANIMAL_TYPE . Mais ne vous inquiétez pas d'oublier, car TypeScript vous rappellera. ?

Dès la lecture

Si vous souhaitez en savoir plus, je recommande de lire la documentation TypeScript sur le rétrécissement du type. Cela nous donnera un aperçu plus approfondi de ce dont nous discutons ici. Il y a une section sur les assertions de type dans ce lien. Ceux-ci vous permettent de définir vos propres vérifications personnalisées pour affiner les types sans utiliser de discriminateurs de type ou s'appuyer sur le in -clé.

en conclusion

Au début de cet article, j'ai dit, dans l'exemple suivant, pourquoi weight est la seule propriété accessible:

 interface chat {
  Poids: numéro;
  Whiskers: numéro;
}
chien d'interface {
  Poids: numéro;
  Friendly: booléen;
}
Laissez l'animal: chien | Cat;
Copier après la connexion
Copier après la connexion

Ce que nous avons appris, c'est que TypeScript ne sait animal peut être Dog ou Cat , mais pas les deux. Par conséquent, nous ne pouvons que prendre weight , qui est la seule propriété publique entre les deux.

Le concept de distinction des types d'union est la façon dont TypeScript distingue ces objets, et cette approche est très évolutive, même pour les plus grandes collections d'objets. Par conséquent, nous devons créer une nouvelle propriété ANIMAL_TYPE sur les deux types qui contient une seule valeur littérale que nous pouvons utiliser pour vérifier. Bien sûr, c'est une autre chose qui doit être suivie, mais elle produit également des résultats plus fiables - ce qui est exactement ce que nous voulons de TypeScript en premier lieu.

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 de ce site Web
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
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal