TypeScript 请勿在不同品牌的数值类型上进行数学运算,

5m1hhzi4  于 9个月前  发布在  TypeScript
关注(0)|答案(3)|浏览(91)

🔎 搜索词

number numeric branded types plus minus add subtract

🕗 版本与回归信息

  • 这是我在每个版本中尝试的行为,我查阅了关于名义类型(标记的、品牌的)的FAQ条目。

⏯ Playground链接

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

💻 代码

  1. type Currency<T> = number & { __currency: T };
  2. type Euro = Currency<"euro">;
  3. type USD = Currency<"usd">;
  4. function canPurchaseItem(priceInEuro: Euro, walletInUSD: USD) {
  5. // No type error, but I would have expected one
  6. return walletInUSD > priceInEuro;
  7. }

🙁 实际行为

EuroUSD -两种不同的品牌数字类型-可以与二进制操作符(如 -)进行比较。

🙂 预期行为

这是两种不同的品牌数字类型。我本以为这两种类型的二进制操作是不允许的。
更技术地说,如果一个数学二进制操作包含:

  • 一个值,它是 number 和某个对象类型的交集
  • 另一个值,它不能分配给该类型

...那么我希望收到一个类型错误。

关于问题的附加信息

根据 #202,TypeScript实际上并没有正式包括一个内置的品牌/名义类型。但是其他不匹配的操作符是被禁止的[不匹配操作符的Playground]:

k0pti3hp

k0pti3hp1#

我认为没有一种启发式方法适用于所有用例。例如,我可能会认为 Price * TaxRate 应该被允许。
为了满足这个功能请求,我认为 TypeScript 需要支持“true”名义类型,以便可以配置不同类型之间的交互。

s1ag04yj

s1ag04yj2#

即使是名义上的类型,你也需要像 #42218 这样的东西,才能对数学运算符产生任何影响。

kulphzqa

kulphzqa3#

我认为没有一种启发式方法适用于所有用例。例如,我可能会认为 Price * TaxRate 应该被允许。
为了满足这个功能请求,我认为 TypeScript 需要支持“true”名义类型,以便可以在不同类型之间进行可配置的交互。
匹配类型实际上只对加法或减法有要求。
例如,5m/s + 3m/s是有意义的,但5m/s + 2小时没有有用的结果。乘法和除法通常会创建新的单位:1$ / 2€ = 0.5 $/€

相关问题