TypeScript не поддерживает прямую перегрузку операторов (operator overloading) — возможна только имитация этого поведения на уровне функций/классов, так как JavaScript (и трансляция TypeScript в JS) не предусматривают возможности менять поведение стандартных операторов (+, *, - и др.) для пользовательских типов.
История вопроса: в языках как C++ или C# есть возможность задавать собственное поведение для операторов при работе с объектами. В TypeScript (и JavaScript) такого нет, потому что на выходе получается обычный JS-код, где операторы жёстко связаны с внутренними типами.
Проблема: при разработке классов с абстрактными сущностями (например, векторы, матрицы, денежные суммы и т. д.) бывает необходимо реализовать удобную работу с ними через операторы. В TypeScript нет синтаксиса, который позволит это сделать нативно.
Решение: для имитации операторной перегрузки создают методы с наглядными именами (add, mul, sub), иногда используют статические методы или функции-утилиты. Плюс, можно реализовать явное приведение типов через метод valueOf, но этого недостаточно для полной перегрузки всех операторов, и это решение работает только для некоторых операторов для примитивных значений.
Пример кода:
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 }
Ключевые особенности:
add, sub)valueOf работает только для некоторых операторов, ограниченноЕсли определить valueOf/toString, будет ли работать перегрузка оператора + для классов?
Нет. valueOf влияет только на поведение при приведении типа к примитиву. Для операторов + (как конкатенация строк или сложение чисел) это может дать неожиданный результат, остальные операторы не настраиваются.
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, но это не объект Currency!
Можно ли использовать Proxy для перегрузки операторов в TypeScript?
Нет. Proxy позволяет перехватывать доступ к свойствам и методы, но не работу операторов (+, *, и т.д.), они работают только с встроенными типами.
Можно ли "перегрузить" оператор через декларацию в интерфейсе или type?
Нет. В интерфейсах можно описать только методы и сигнатуры функций, нельзя описать операторные перегрузки как, например, в C# (operator+)
Разработчик добавил valueOf в класс Currency, чтобы получать числовое представление и выполнять математические операции напрямую (currency1 + currency2). В итоге терялась семантика; результат сложения — простое число, а не валютный объект, невозможно было отследить тип возвращаемого значения.
Плюсы:
Минусы:
В классе Vector реализован метод add, возвращающий новый Vector. Чётко типизировано, невозможны двусмысленности.
Плюсы:
Минусы: