microsoft / microsoft/TypeScript

Don't allow math operations on different branded numeric types

Open
#59,423 3 comments 3 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Awaiting More Feedback Suggestion
Dominant language
Go
Stars
111k
Forks
14.4k
Avg merge
1d 19h
Merged PRs (30d)
117

Description

🔎 Search Terms

number numeric branded types plus minus add subtract

🕗 Version & Regression Information
  • This is the behavior in every version I tried, and I reviewed the FAQ for entries about Nominal types (tagged, branded)
⏯ Playground Link

https://www.typescriptlang.org/play/?#code/C4TwDgpgBAwgrgJwRAdgYxAHgCoD4oC8UKcAtgEYQJQBkUA3lAPpNqLLogBcU2UAvgG4AUKEhQAoogD2hWO1QZMAIggzluEWOgBVAMoAROfCSKsyuAGcAJhpHCAZnHTAAltJRQ0AQxQAFRDQAC29LCABJYAhSAAowBFc0CJQpBGkeVOkAGigAd28AGwKIYHCUfQMeCoBKBmEoBqgAeiaoADlZbSgqNIQc8jhgKHC86TgC6ygQgDdoCAAPSDQoyY8IesbkYERPfKKSsoqofHjE5MyRfmEgA

💻 Code
type Currency<T> = number & { __currency: T };
type Euro = Currency<"euro">;
type USD = Currency<"usd">;

function canPurchaseItem(priceInEuro: Euro, walletInUSD: USD) {
    // No type error, but I would have expected one
    return walletInUSD > priceInEuro;
}
🙁 Actual behavior

Euro and USD -two different branded numeric types- can be compared with binary operators such as -.

🙂 Expected behavior

These are two different branded numeric types. I would have expected that binary operations between the two of them would be disallowed.

More technically, if a mathematical binary operation contains:

  • one value that is an intersection of number and some object type
  • another value that is not assignable to that type

...then I'd expect to receive a type error.

Additional information about the issue

Per #202, TypeScript doesn't actually formally include a built-in branded/nominal typing. But other mismatched operators are disallowed [playground of mismatched operators]:

// These are all type errors:
console.log([] + []);
console.log([] + {});
console.log([] + 1);
console.log({} + 1);
console.log({} + {});
console.log({ a: 1 } + { b: 2 });

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the provided Playground example and compare it with the linked mismatched-operator example to understand the current checking behavior. The work is done when operations between distinct branded numeric intersections produce the expected type errors without regressing the existing mismatched-operator errors.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
compilers
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.