ProgrammingTypeScript Architect

How to implement operator overloading in TypeScript, is it possible directly, and what are the workarounds?

Pass interviews with Hintsage AI assistant

Answer.

TypeScript does not support direct operator overloading — only imitation of this behavior is possible at the function/class level, as JavaScript (and TypeScript's compilation to JS) does not provide the ability to change the behavior of standard operators (+, *, -, etc.) for user-defined types.

History of the issue: in languages like C++ or C#, it is possible to define custom behavior for operators when working with objects. In TypeScript (and JavaScript), there is no such functionality because the output is regular JS code, where operators are firmly tied to internal types.

Problem: when developing classes with abstract entities (e.g., vectors, matrices, amounts of money, etc.), it is often necessary to implement convenient work with them through operators. There is no syntax in TypeScript that allows this to be done natively.

Solution: to imitate operator overloading, methods with clear names (add, mul, sub) are created, sometimes static methods or utility functions are used. Additionally, explicit type conversion can be implemented via the valueOf method, but this is not sufficient for full overloading of all operators, and this solution works only for some operators for primitive values.

Code example:

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 }

Key features:

  • No built-in operator overloading support
  • Explicit methods (add, sub) are used
  • The valueOf method works only for some operators, limitedly

Trick questions.

If you define valueOf/toString, will the + operator overloading work for classes?

No. valueOf affects only behavior when converting to a primitive type. For + operators (like string concatenation or numeric addition), this may yield unexpected results; other operators cannot be configured.

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, but this is not a Currency object!

Can you use Proxy for operator overloading in TypeScript?

No. Proxy allows intercepting access to properties and methods but not operator work (+, *, etc.), which only work with built-in types.

Can an operator be "overloaded" through declaration in an interface or type?

No. In interfaces, you can only describe methods and function signatures, you cannot describe operator overloads as, for example, in C# (operator+)

Common mistakes and anti-patterns

  • Trying to write functions like operator+(a, b) and hoping for their operation
  • Using valueOf to implement business logic (the valueOf method is a template that makes the code implicit)
  • Combining in one class primitive value substitution and class logic

Real-life example

Negative case

A developer added valueOf to the Currency class to get a numeric representation and perform mathematical operations directly (currency1 + currency2). As a result, the semantics were lost; the result of addition was a simple number, not a currency object, and it became impossible to track the type of the returned value.

Pros:

  • concise expression (currency1 + currency2)
  • less code for basic operations

Cons:

  • type safety is lost
  • inability to control the returned object
  • confusing debugging

Positive case

In the Vector class, a method add returns a new Vector. It is clearly typed, and ambiguities are impossible.

Pros:

  • strict typing
  • operation safety
  • ease of maintenance

Cons:

  • it is impossible to write v1 + v2, only v1.add(v2)
  • slightly bulkier notation than in languages with operator overloading