ProgrammationArchitecte TypeScript

Comment mettre en œuvre la surcharge des opérateurs (operator overloading) en TypeScript, est-ce possible directement, et quelles sont les méthodes alternatives ?

Réussissez les entretiens avec l'assistant IA Hintsage

Réponse.

TypeScript ne supporte pas la surcharge directe des opérateurs (operator overloading) - seule l'imitation de ce comportement est possible au niveau des fonctions/classes, car JavaScript (et la transpilation de TypeScript en JS) ne prévoient pas la possibilité de changer le comportement des opérateurs standard (+, *, -, etc.) pour les types personnalisés.

Historique de la question : dans des langages comme C++ ou C#, il est possible de définir un comportement personnalisé pour les opérateurs lors de l'utilisation d'objets. En TypeScript (et JavaScript), cela n'existe pas, car le code résultant est du JS classique, où les opérateurs sont strictement liés aux types internes.

Problème : lors de la conception de classes avec des entités abstraites (par exemple, des vecteurs, des matrices, des sommes d'argent, etc.), il peut être nécessaire de permettre un travail pratique avec elles via des opérateurs. TypeScript n'a pas de syntaxe qui permettrait de faire cela de manière native.

Solution : pour imiter la surcharge des opérateurs, on crée des méthodes avec des noms explicites (add, mul, sub), et parfois on utilise des méthodes statiques ou des fonctions utilitaires. De plus, on peut réaliser une conversion explicite des types via la méthode valueOf, mais cela ne suffit pas pour la surcharge complète de tous les opérateurs, et cette solution ne fonctionne que pour certains opérateurs pour des valeurs primitives.

Exemple de code :

class Vector2D { constructor(public x: number, public y: number) {} add(v: Vector2D): Vector2D { return new Vector2D(this.x + v.x, this.y + v.y); } } const v1 = new Vector2D(1, 2); const v2 = new Vector2D(3, 4); const result = v1.add(v2); // Vector2D { x: 4, y: 6 }

Caractéristiques clés :

  • Pas de support intégré pour la surcharge d'opérateurs
  • Utilisation de méthodes explicites (add, sub)
  • La méthode valueOf fonctionne uniquement pour certains opérateurs, de manière limitée

Questions pièges.

Si l'on définit valueOf/toString, la surcharge de l'opérateur + fonctionnera-t-elle pour les classes ?

Non. valueOf n'influence que le comportement lors de la conversion de types en primitif. Pour les opérateurs + (comme la concaténation de chaînes ou l'addition de nombres), cela peut donner des résultats inattendus, les autres opérateurs ne sont pas configurables.

class Currency { constructor(private amount: number) {} valueOf() { return this.amount; } } const c1 = new Currency(10); const c2 = new Currency(5); console.log(c1 + c2); // 15, mais ce n'est pas un objet Currency !

Peut-on utiliser Proxy pour la surcharge d'opérateurs en TypeScript ?

Non. Proxy permet d'intercepter l'accès aux propriétés et aux méthodes, mais pas le travail avec les opérateurs (+, *, etc.), ceux-ci ne fonctionnent qu'avec des types intégrés.

Peut-on "surcharger" un opérateur via une déclaration dans une interface ou type ?

Non. Dans les interfaces, on ne peut décrire que des méthodes et des signatures de fonctions, il n'est pas possible de décrire des surcharges d'opérateurs comme, par exemple, en C# (operator+)

Erreurs types et anti-patrons

  • Essayer d'écrire des fonctions de type operator+(a, b) et espérer leur bon fonctionnement
  • Utiliser valueOf pour réaliser de la logique métier (la méthode valueOf rend le code implicite)
  • Mélanger dans une même classe le remplacement de valeur primitive et la logique de classe

Exemple concret

Cas négatif

Un développeur a ajouté valueOf dans la classe Currency pour obtenir une représentation numérique et effectuer des opérations mathématiques directement (currency1 + currency2). Au final, la sémantique était perdu ; le résultat de l'addition - un simple nombre, et non un objet monétaire, il était impossible de suivre le type de valeur retournée.

Avantages :

  • expression concise (currency1 + currency2)
  • moins de code pour les opérations basiques

Inconvénients :

  • perte de sécurité typique
  • impossibilité de contrôler l'objet retourné
  • débogage compliqué

Cas positif

Dans la classe Vector, une méthode add a été implémentée, retournant un nouveau Vector. C'est clairement typé, aucune ambiguïté n'est possible.

Avantages :

  • typage strict
  • sécurité des opérations
  • facilité de maintenance

Inconvénients :

  • impossibilité d'écrire v1 + v2, seulement v1.add(v2)
  • une syntaxe légèrement plus encombrante que dans les langages avec surcharge d'opérateurs