Skip to content

Experimental TypeScript fork with operator overloading and overload dispatch—documenting a working implementation #62584

@adrianstephens

Description

@adrianstephens

🔍 Search Terms

operator overload, operator, overload, dispatch, runtime dispatch

✅ Viability Checklist

⭐ Suggestion

🧠 Summary

This issue documents a working fork of TypeScript—published as @isopodlabs/typescript—that implements two long-requested features:

  • Operator Overloading: Transforms expressions like a + b into method calls (a.add(b)) based on operand types.
  • Function Overload Dispatch: Rewrites calls to overloaded functions using mangled names based on argument types.

I had to check a box above in order to post this, but in reality both features rely on type-dependent emit, which has historically been considered out-of-scope for TypeScript. This fork is intended as a proof of concept to explore whether such transformations can be implemented safely, predictably, and in a way that aligns with TypeScript’s broader goals.


🔍 Motivation

Operator overloading and overload dispatch are frequently requested, especially in domains like:

  • Vector math and geometry
  • Symbolic computation
  • DSLs and fluent APIs
  • Game engines and physics simulations

Current workarounds (e.g., method chaining, manual overload resolution) are verbose and error-prone. This fork demonstrates that these features can be implemented without breaking existing code, without introducing runtime ambiguity, and with full reproducibility via CLI flags.


⚙️ Implementation Overview

The fork introduces two compiler options:

  • operatorOverloading: Enables transformation of operator expressions into method calls.
  • functionOverloadDispatch: Enables mangling and dispatch of overloaded functions based on argument types.

Operator Overloading

  • Uses a fixed mapping from operators to method names (+ → add, - → sub, etc.).
  • Resolves overloads at compile time using the type checker.
  • Falls back to standard behavior if no matching method is found.

Function Overload Dispatch

  • Generates mangled names for each overload (foo(x: number)foo$n).
  • Rewrites calls based on argument types.
  • Supports overloads for operator methods as well.

Full documentation and examples are available in the README.


🧪 Type-Dependent Emit: A Reconsideration

TypeScript’s design goals discourage type-dependent emit to avoid:

  • Runtime behavior changes based on types
  • Hidden transformations that break predictability
  • Incompatibility with JavaScript semantics

This implementation attempts to sidestep those concerns:

  • No runtime type checks: All transformations are compile-time only.
  • No new JS semantics: Transformed code is valid, readable JavaScript.
  • Fully opt-in: Requires explicit compiler flags.
  • Reproducible and transparent: CLI-driven builds with no ambient leakage.

I recognize that type-dependent emit is a sensitive topic, but I hope this fork can serve as a concrete example to evaluate whether the objections still hold in this specific context.


🙏 Closing Thoughts

This issue is not a feature request for upstream inclusion, but an invitation to examine a working implementation that explores a long-standing community interest. I welcome critique, discussion, and feedback on the design tradeoffs—and I’m open to learning where this approach may fall short of TypeScript’s goals.

📃 Motivating Example

  • Operator Overloading: Transforms expressions like a + b into method calls (a.add(b)) based on operand types.
  • Function Overload Dispatch: Rewrites calls to overloaded functions using mangled names based on argument types.

💻 Use Cases

  1. What do you want to use this for?
    Linear Algebra and arbitrary-precision arithmetic.
    Removing the cost of runtime dispatching on type when the compiler already knows the type
  2. What shortcomings exist with current approaches?
    Using methods for operators is hard to read, error prone, ugly, etc.
  3. What workarounds are you using in the meantime?
    I couldn't stomach the workarounds, so I made this :)

Metadata

Metadata

Assignees

No one assigned

    Labels

    DiscussionIssues which may not have code impact

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions