为什么 BigInt 要求从 Number 显式转换?

Why BigInt demand explicit conversion from Number?

BigInt数字 转换

在 JavaScript 中处理数字时,有两种原始类型可供选择 - BigInt 和 Number。人们可能期望从“smaller”类型到“bigger”类型的隐式转换,这在 JavaScript 中不是这种情况。

预计

在计算 BigInt 和 Number 的某些组合时,用户可能会像下面的示例那样从 Number 隐式转换为 BigInt:

const number = 16n + 32; // DOESN'T WORK
// Expected: Evaluates to 48n

实际行为

同时对 BigInt 和 Number 进行运算的表达式抛出错误:

const number = 16n + 32; 
// Throws "TypeError: Cannot mix BigInt and other types, use explicit conversions"

为什么在上述情况下需要显式转换?

或者换句话说,这种设计背后的原因是什么?

它们不是 "smaller" 和 "bigger"。一个有真实但可能不精确的数字,另一个有完整但精确的数字。你认为 16n + 32.5 的结果应该是什么? (请注意,在类型方面,3232.5 之间没有区别)。自动转换为 BigInt 会丢失任何小数值;自动转换为 Number 将面临精度损失和潜在溢出的风险。显式转换的要求迫使程序员选择他们想要的行为,而不是将其作为潜在(很有可能)的错误来源。

原始 BigInt 提案中记录了这一点:https://github.com/tc39/proposal-bigint/blob/master/README.md#design-goals-or-why-is-this-like-this

When a messy situation comes up, this proposal errs on the side of throwing an exception rather than rely on type coercion and risk giving an imprecise answer.

这是一种设计选择。在静态类型语言中,强制转换可能会导致信息丢失,例如从 float 到 int 小数部分会被截断。 JavaScript 确实类型强制,您可能希望 16n + 32 只使用 32 就好像它是 BigInt 而不是 Number 一样,不会有问题。 这纯粹是一种设计选择,其动机是 this part of the documentation

您可能错过了一个重点:
BigInt 是关于整数的
数字是关于实数的
从 32 到 32n 的隐式转换可能有意义,但从浮点数隐式转换例如1.555 到 BigInt 会产生误导。