ProgrammationDéveloppeur Fullstack

Qu'est-ce que le Declaration Merging en TypeScript et comment cela fonctionne-t-il en pratique ?

Réussissez les entretiens avec l'assistant IA Hintsage

Réponse.

Historique de la question

Le Declaration Merging est une caractéristique unique de TypeScript qui permet de combiner plusieurs déclarations avec les mêmes noms en une seule entité. Cela est dû à l'histoire de TypeScript en tant que typage sur JavaScript : de nombreuses bibliothèques tierces déclaraient des interfaces, des fonctions, des espaces de noms, et TypeScript devait permettre de les étendre sans modifier le code source de la bibliothèque.

Problème

Dans des API complexes et lors de la typage de bibliothèques JS tierces, il peut être nécessaire de diviser la responsabilité — par exemple, étendre les types d'un module, ajouter des champs à une interface, combiner des noms. Cependant, la plupart des langages ne prennent pas en charge une telle combinaison de déclarations.

Solution

TypeScript permet de fusionner (merge) les déclarations d'interfaces, d'espaces de noms, de fonctions, de classes avec des noms identiques, ce qui rend l'API flexible pour l'extension. Il est utilisé pour étendre des types tiers, ajouter des méthodes personnalisées aux bibliothèques, ainsi que pour organiser du code modulaire.

Exemple de code :

// interfaces merging interface User { id: number; } interface User { name: string; } const u: User = { id: 1, name: "Jack" }; // namespace + function merging function greet() { return "Hi!"; } namespace greet { export function loud() { return "HI!"; } } greet(); // "Hi!" greet.loud(); // "HI!"

Caractéristiques clés :

  • Permet de combiner des interfaces, des fonctions avec namespace, des enums avec namespace, mais pas des types.
  • Utilisé pour décrire des API extensibles et des extensions globales de déclarations.
  • Permet de modifier/étendre en toute sécurité les types des bibliothèques tierces sans les modifier.

Questions pièges.

Peut-on fusionner des type alias de manière similaire aux interfaces ?

Non, les type alias ne peuvent pas être fusionnés. En essayant de déclarer plusieurs types avec le même nom, une erreur de compilation se produira.

type T = { a: string }; type T = { b: number }; // Erreur

TypeScript insérera-t-il des champs d'interface/espace de noms dans un ordre aléatoire ?

La structure fusionnée est toujours construite dans l'ordre de la déclaration — si des noms de propriétés identiques existent, la dernière déclaration "l'emporte".

Les méthodes d'une interface sont-elles fusionnées en une seule fonction ?

Non, les méthodes avec des noms identiques dans différentes interfaces ne fusionnent pas en une seule fonction — si les signatures coïncident, TypeScript n'autorise pas et n'autorise pas l'implémentation des "deux" variantes.

Erreurs typiques et anti-patterns

  • Tentatives de fusionner des type alias ou des enums sans namespace — cela entraînera une erreur.
  • Champs répétitifs avec des types différents à l'intérieur des interfaces — conflit, ne fusionnent pas ;
  • Utiliser le merging sans nécessité consciente — conduit à un code peu lisible.

Exemple de la vie réelle

Cas négatif

Une entreprise définit l'interface globale Window deux fois avec des champs différents et des types différents pour un champ avec le même nom. Lors de la compilation, le compilateur ne détecte pas le problème, mais au moment de l'exécution, un conflit de types imprévu apparaît.

Avantages :

  • Possibilité rapide d'"étendre" une interface sans changer la source.

Inconvénients :

  • Des noms conflictuels entraînent des bugs, difficiles à trouver.
  • Souvent complique la compréhension de la structure complète du type.

Cas positif

Un fichier d.ts est écrit pour une bibliothèque tierce, où l'interface de l'API est étendue par des modules séparés sans changer la bibliothèque elle-même, toutes les extensions sont documentées, la politique de nommage est décrite dans le Wiki.

Avantages :

  • Extension sécurisée de l'API tierce.
  • Améliorations et ajouts peuvent être effectués progressivement.

Inconvénients :

  • Nécessite de maintenir la documentation des correspondances et du nommage.
  • Risque accru de conflits dans une grande équipe sans politique de nommage stricte.