Mr Josselin A - TypeScript









Déclaration de fusion

Références

L'actualité

Librairie

L'information

Introduction

Certains des concepts uniques de TypeScript décrivent la forme des objets JavaScript au niveau du type. Un exemple particulièrement spécifique à TypeScript est le concept de "déclaration en fusion". Comprendre ce concept vous donnera un avantage lorsque vous utiliserez du code JavaScript existant. Cela ouvre également la porte à des concepts d'abstraction plus avancés.

Dans le cadre de cet article, "Déclarations de fusion" signifie que le compilateur fusionne deux déclarations distinctes déclarées avec le même nom dans une même définition. Cette définition fusionnée présente les caractéristiques des deux déclarations originales. Vous pouvez fusionner n'importe quel nombre de déclarations. Cela ne se limite pas à deux déclarations.

Concepts de base

Dans TypeScript, une déclaration crée des entités dans au moins un des trois groupes suivants : espace de nom, type ou valeur. Les déclarations créant un espace de noms créent un espace de noms, qui contient les noms auxquels on accède à l'aide d'une notation en pointillé. Les déclarations de création de type ne font que cela: elles créent un type visible avec la forme déclarée et lié au nom donné. Enfin, les déclarations de création de valeur créent des valeurs visibles dans le code JavaScript de sortie.

Type de déclaration Espace de noms Type Veleur
Espace de noms X X
Classe X X
Enum X X
Interface X
Type Alias X
Fonction X
Variable X

Comprendre ce qui est créé avec chaque déclaration vous aidera à comprendre ce qui est fusionné lorsque vous effectuez une fusion de déclaration.

Fusion d'interfaces

Le type de fusion de déclaration le plus simple, et peut-être le plus courant, est la fusion d'interfaces. Au niveau le plus élémentaire, la fusion joint mécaniquement les membres des deux déclarations en une interface unique portant le même nom.


Les membres non fonctionnels des interfaces doivent être uniques. S'ils ne sont pas uniques, ils doivent être du même type. Le compilateur émettra une erreur si les interfaces déclarent toutes les deux un membre non-fonction du même nom, mais de types différents.

Pour les membres de fonction, chaque membre de fonction du même nom est traité comme décrivant une surcharge de la même fonction. Il est à noter également que dans le cas d'une fusion A d'interface avec une interface plus récente A, la deuxième interface aura une priorité plus élevée que la première.

C'est, dans l'exemple:

Les trois interfaces fusionneront pour créer une déclaration unique de la manière suivante:

Notez que les éléments de chaque groupe conservent le même ordre, mais les groupes eux-mêmes sont fusionnés avec les ensembles de surcharge ultérieurs ordonnés en premier.

Les signatures spécialisées constituent une exception à cette règle. Si une signature a un paramètre dont le type est un type littéral de chaîne unique (par exemple, il ne s'agit pas d'une union de littéraux de chaîne), elle sera ensuite renvoyée vers le haut de sa liste de surcharge fusionnée.

Par exemple, les interfaces suivantes vont fusionner:

La déclaration de fusion fusionnée qui en résulte Documentsera la suivante :


Fusion de Namespaces

De même que pour les interfaces, les espaces de noms du même nom fusionneront également leurs membres. Comme les espaces de noms créent à la fois un espace de noms et une valeur, nous devons comprendre comment les deux fusionnent.

Pour fusionner les espaces de noms, les définitions de types d'interfaces exportées déclarées dans chaque espace de noms sont elles-mêmes fusionnées, formant ainsi un seul espace de noms contenant les définitions d'interface fusionnées.

Pour fusionner la valeur de l'espace de noms, sur chaque site de déclaration, s'il existe déjà un espace de noms portant le nom donné, il est ensuite étendu en prenant l'espace de noms existant et en ajoutant les membres exportés du second espace de noms au premier.

La déclaration de fusion de Animals dans cet exemple :

est équivalent à:

Ce modèle de fusion d'espaces de noms constitue un point de départ utile, mais nous devons également comprendre ce qui se passe avec les membres non exportés. Les membres non exportés ne sont visibles que dans l'espace de noms d'origine (non fusionné). Cela signifie qu'après la fusion, les membres fusionnés provenant d'autres déclarations ne peuvent pas voir les membres non exportés.

Nous pouvons le voir plus clairement dans cet exemple:

Parce que haveMuscles n'est pas exporté, seule la fonction animalsHaveMuscles qui partage le même espace de nom non fusionné peut voir le symbole. La fonction doAnimalsHaveMuscles, même si elle fait partie de l'espace Animal de noms fusionné, ne peut pas voir ce membre non exporté.

Fusion de Namespaces avec des classes, des fonctions et des énumérations

Les espaces de noms sont suffisamment souples pour pouvoir également fusionner avec d'autres types de déclarations. Pour ce faire, la déclaration d'espace de noms doit suivre la déclaration avec laquelle elle fusionnera. La déclaration résultante a les propriétés des deux types de déclaration. TypeScript utilise cette fonctionnalité pour modéliser certains modèles en JavaScript ainsi que d'autres langages de programmation.

Fusionner des espaces de noms avec des classes

Cela donne à l'utilisateur un moyen de décrire les classes internes.

Les règles de visibilité pour les membres fusionnés sont identiques à celles décrites dans la section "Fusion d'espaces de noms". Nous devons donc exporter la classe AlbumLabel pour que la classe fusionnée puisse le voir. Le résultat final est une classe gérée à l'intérieur d'une autre classe. Vous pouvez également utiliser des espaces de noms pour ajouter plus de membres statiques à une classe existante.

Outre le modèle des classes internes, vous connaissez peut-être également la pratique JavaScript consistant à créer une fonction, puis à l'étendre davantage en ajoutant des propriétés à la fonction. TypeScript utilise la fusion de déclarations pour construire des définitions comme celle-ci d'une manière sûre pour le type.

De même, les espaces de noms peuvent être utilisés pour étendre des énumérations avec des membres statiques :


Fusions interdites

Toutes les fusions ne sont pas autorisées dans TypeScript. Actuellement, les classes ne peuvent pas fusionner avec d'autres classes ou avec des variables. Pour plus d'informations sur l'imitation de la fusion de classes, voir la section Mixins dans TypeScript.

Augmentation de module

Bien que les modules JavaScript ne prennent pas en charge la fusion, vous pouvez corriger les objets existants en les important puis en les mettant à jour. Regardons un exemple de jouet observable :

Cela fonctionne aussi très bien dans TypeScript, mais le compilateur ne le sait pas Observable.prototype.map. Vous pouvez utiliser l'augmentation de module pour en informer le compilateur :

Le nom du module est résolu de la même manière que les spécificateurs de module dans import / export. Voir Modules pour plus d'informations. Ensuite, les déclarations d'une augmentation sont fusionnées comme si elles avaient été déclarées dans le même fichier que le fichier d'origine. Cependant, vous ne pouvez pas déclarer de nouvelles déclarations de niveau supérieur dans l'augmentation, mais simplement des correctifs pour les déclarations existantes.

Augmentation globale

Vous pouvez également ajouter des déclarations à la portée globale à partir d'un module:

Les augmentations globales ont le même comportement et les mêmes limites que les augmentations de module.