TypeScript unterstützt keine direkte Operatorüberladung — es ist nur eine Simulation dieses Verhaltens auf Funktions-/Klassenebene möglich, da JavaScript (und die Übersetzung von TypeScript in JS) nicht die Möglichkeit bietet, das Verhalten von Standardoperatoren (+, *, - usw.) für benutzerdefinierte Typen zu ändern.
Historie: In Sprachen wie C++ oder C# gibt es die Möglichkeit, eigenes Verhalten für Operatoren im Umgang mit Objekten festzulegen. In TypeScript (und JavaScript) gibt es dies nicht, weil der ausgegebene Code gewöhnlicher JS-Code ist, bei dem Operatoren fest mit internen Typen verknüpft sind.
Problem: Bei der Entwicklung von Klassen mit abstrakten Entitäten (z. B. Vektoren, Matrizen, Geldbeträge usw.) ist es manchmal notwendig, eine bequeme Arbeit mit ihnen über Operatoren zu ermöglichen. TypeScript hat keine Syntax, die dies nativ ermöglicht.
Lösung: Um die Operatorüberladung zu simulieren, erstellt man Methoden mit anschaulichen Namen (add, mul, sub), manchmal werden auch statische Methoden oder Hilfsfunktionen verwendet. Zudem kann eine explizite Typumwandlung über die Methode valueOf implementiert werden, aber das reicht nicht für eine vollständige Überladung aller Operatoren aus, und diese Lösung funktioniert nur für einige Operatoren für primitive Werte.
Beispielcode:
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 }
Hauptmerkmale:
add, sub)valueOf funktioniert nur für einige Operatoren, begrenztWenn man valueOf/toString definiert, wird die Überladung des Operators + für Klassen funktionieren?
Nein. valueOf beeinflusst nur das Verhalten bei der Typumwandlung in ein Primitiv. Für die Operatoren + (wie die Verkettung von Zeichenfolgen oder die Addition von Zahlen) kann dies unerwartete Ergebnisse liefern, die anderen Operatoren sind nicht konfigurierbar.
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, aber das ist kein Currency-Objekt!
Kann man Proxy zur Überladung von Operatoren in TypeScript verwenden?
Nein. Proxy ermöglicht es, den Zugriff auf Eigenschaften und Methoden abzufangen, jedoch nicht die Arbeit mit Operatoren (+, *, usw.), diese funktionieren nur mit eingebauten Typen.
Kann man einen Operator durch Deklaration im Interface oder Typ "überladen"?
Nein. In Interfaces kann man nur Methoden und Funktionssignaturen beschreiben, man kann keine Operatorüberladungen beschreiben, wie zum Beispiel in C# (operator+)
Ein Entwickler hat valueOf in die Klasse Currency eingefügt, um eine numerische Darstellung zu erhalten und mathematische Operationen direkt auszuführen (currency1 + currency2). Am Ende ging die Semantik verloren; das Ergebnis der Addition war eine einfache Zahl und kein Währungsobjekt, es war nicht möglich, den Typ des Rückgabewertes zu verfolgen.
Vorteile:
Nachteile:
In der Klasse Vector wurde eine Methode add implementiert, die einen neuen Vector zurückgibt. Es ist klar typisiert, es gibt keine Mehrdeutigkeiten.
Vorteile:
Nachteile: