TypeScript non supporta il sovraccarico diretto degli operatori (operator overloading) — è possibile solo simulare questo comportamento a livello di funzioni/classi, poiché JavaScript (e la traduzione di TypeScript in JS) non prevedono la possibilità di modificare il comportamento degli operatori standard (+, *, - e altri) per i tipi personalizzati.
Storia della questione: in linguaggi come C++ o C# c'è la possibilità di definire un comportamento personalizzato per gli operatori quando si lavora con oggetti. In TypeScript (e JavaScript) ciò non è possibile, perché il risultato è un normale codice JS, dove gli operatori sono rigidamente legati ai tipi interni.
Problema: quando si sviluppano classi con entità astratte (ad esempio, vettori, matrici, somme di denaro, ecc.), può essere necessario implementare un lavoro conveniente con esse tramite operatori. In TypeScript non esiste una sintassi che permetta di farlo in modo nativo.
Soluzione: per simulare il sovraccarico degli operatori si creano metodi con nomi chiari (add, mul, sub), a volte si usano metodi statici o funzioni utilitarie. Inoltre, è possibile implementare una conversione esplicita dei tipi tramite il metodo valueOf, ma questo non è sufficiente per un sovraccarico completo di tutti gli operatori e questo approccio funziona solo per alcuni operatori per valori primitivi.
Esempio di codice:
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 }
Caratteristiche chiave:
add, sub)valueOf funziona solo per alcuni operatori, in modo limitatoSe definisco valueOf/toString, funzionerà il sovraccarico dell'operatore + per le classi?
No. valueOf influisce solo sul comportamento durante la conversione del tipo in primitivo. Per gli operatori + (come la concatenazione di stringhe o l'addizione di numeri) questo può dare risultati inaspettati, gli altri operatori non sono configurabili.
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, ma non è un oggetto Currency!
Posso usare Proxy per sovraccaricare gli operatori in TypeScript?
No. Proxy consente di intercettare l'accesso a proprietà e metodi, ma non l'uso degli operatori (+, *, ecc.), che funzionano solo con i tipi integrati.
Posso "sovraccaricare" un operatore tramite dichiarazione in un'interfaccia o type?
No. Negli interfacce è possibile descrivere solo metodi e firme di funzione, non è possibile descrivere sovraccarichi di operatori come, ad esempio, in C# (operator+)
Un sviluppatore ha aggiunto valueOf alla classe Currency per ottenere una rappresentazione numerica e eseguire operazioni matematiche direttamente (currency1 + currency2). Di conseguenza, si perdeva la semantica; il risultato dell'addizione era un semplice numero, e non un oggetto valuta, impossibile da rintracciare il tipo di valore restituito.
Pro:
Contro:
Nella classe Vector è stato implementato un metodo add che restituisce un nuovo Vector. È chiaramente tipizzato, non ci sono ambiguità.
Pro:
Contro: