typescript - 为什么 TS 在一元算术运算中不安全,但在二进制算术运算中不安全?

标签 typescript math compiler-construction

算术 以下是正确的:让 'a' 是任何正实数,所以:

-a = a*(-1)  

Typescript 编译器似乎没有以类型安全的方式重现算术规则。看:

(一)按预期工作

以下几行产生此错误消息:“算术运算的左侧必须是‘any’、‘number’、‘big-int’或枚举类型”

const f = (a: string) => a*(-1)  // error
const g = (a: {}) => a*(-1)      // error

(二)未按预期工作

在下面的场景中,所有算术计算都使用非数字类型不安全地执行,并且不会引发编译时错误。


const f = (a: string) => -a
const g = (a: {}) => -a 

console.log(f('hi there')) // produces 'NaN' !
console.log(g('hi there')) // produces 'NaN'

console.log(g(2)) // produces -2

问题
  • 为什么一元运算符中的 TS 不如二元运算符中的安全?

  • 注意:TS 版本 3.7.2/类型“未知”按预期工作

    最佳答案

    ECMAScript 规范指出 unary + unary - 运算符都执行抽象操作 ToNumber() 在他们的输入表达式上:

    12.5.6 Unary + Operator

    NOTE The unary + operator converts its operand to Number type*.


    12.5.6.1 Runtime Semantics: Evaluation
    UnaryExpression : + UnaryExpression
  • 令 expr 为评估 UnaryExpression 的结果.
  • 返回 ? ToNumber (? GetValue (expr))。

  • 12.5.7 Unary - Operator

    NOTE The unary - operator converts its operand to Number type* and then negates it. Negating +0 produces -0, and negating -0 produces +0.


    12.5.7.1 Runtime Semantics: Evaluation
    UnaryExpression : - UnaryExpression
  • 令 expr 为评估 UnaryExpression 的结果.
  • 让 oldValue 是? ToNumber (? GetValue (expr))。
  • 如果 oldValue 是 NaN,则返回 NaN。
  • 返回对 oldValue 取反的结果;也就是说,计算一个大小相同但符号相反的数字。

  • *强调添加

    TypeScript 没有理由对接受的类型施加任意限制,因为根据规范,主要的预期用途是 执行类型转换 .

    地址 Emanuel Vintilăcomment关于上述问题:

    Binary operators also perform type conversion


    该规范不使用相同的语言,即

    [...] converts its operand to Number type


    MultiplicativeExpression ;也就是说,而乘法* , / , %运算符确实执行类型转换,这不是它们的主要用途。

    关于typescript - 为什么 TS 在一元算术运算中不安全,但在二进制算术运算中不安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59573311/

    相关文章:

    typescript - 使用Vite和TS的Vue项目中的 "typecheck"npm脚本是干什么用的?

    c++ - 检查 C++ 编译器隐式生成的代码

    compiler-construction - 了解编译器中递归闭包的建模

    javascript - 识别带有一个异步函数调用的嵌套 FOR 循环和 IF 语句何时完成

    javascript - typescript :如何说一个变量是时刻类型的?

    javascript - 在 Angular 中将 Promise 从一个服务调用传递到另一个服务调用

    java - 找到一个数字的最接近数字的因子

    algorithm - LUT 与 IEEE-754 32 位浮点的 Newton-Raphson 除法

    MySQL 评级/投票系统(根据票数按最高评级准确排序)

    java - 动态编译语言 vs 静态编译语言