【问题标题】:What does "all legal JavaScript is legal TypeScript" mean?“所有合法的 JavaScript 都是合法的 TypeScript”是什么意思?
【发布时间】:2017-06-04 15:49:57
【问题描述】:

我经常听到人们发表这样的言论

所有 JavaScript 代码都是合法的 TypeScript 代码

TypeScript 是 JavaScript 的超集

但是当我写了一些 完全合法和合理的 JS 代码,它具有完全确定性的行为:

var x = "hello".substr("w").toStrig * { m: 3 / true } + window + parseInt(Element).fzq;

ECMAScript 定义 x 应该具有 "NaN[object Window]undefined" 的值,这看起来完全没问题,但是我从 TypeScript 中得到了一堆错误!那么,“所有 JS 都是 TS”这句话不是谎言吗?有什么关系?

【问题讨论】:

    标签: typescript


    【解决方案1】:

    所有 JavaScript 代码都是合法的 TypeScript 代码

    这是什么意思:

    • TypeScript 不会改变现有 JavaScript 的语法
    • TypeScript 不会改变现有 JavaScript 的行为
    • TypeScript 确实认为某些 JS 代码有类型警告,因为这就是重点

    语法

    TypeScript 将成功解析所有合法的 JavaScript 代码。它将按原样发出此代码(减去降级,例如,如果您的目标是 ES5 或更低版本,则 ES6 箭头函数将转换为等效的 ES5 代码)。如果您愿意,可以忽略此 JS 代码生成的类型警告;类型警告不会阻止 TypeScript 写入输出 .js 文件。

    行为

    TypeScript 不会改变现有 JavaScript 代码的行为,尽管很多人希望这样做!任何通过编译器运行的 JS 代码的行为都与直接运行一样*。

    类型警告

    TypeScript可能对它认为不正确的代码发出类型警告。

    不正确是什么意思?请注意,JavaScript 是确定性的。例如,与 C++ 不同,它基本上不可能导致“实现定义的”行为。 JavaScript 也很少抛出异常;与尝试将对象乘以函数时可能引发异常的其他语言不同,JS 生成NaN。通过拼写错误的名称访问属性将产生undefined 而不是运行时错误(让每个人都非常懊恼)。因此,这里的“不正确”栏故意设置得比“使您的计算机崩溃”或“引发异常”更严格。

    例如,像这样的某些代码是所有合法 JavaScript,甚至不会引发异常。 TypeScript 认为这些行中的每一行都有错误;这通常被使用它的人认为是积极的:

    var x = { } + 3; // Error, can't add objects and numbers
    var y = "hello world".substr(1, 2, 3, 4, 5); // Error, too many parameters
    var z = { x: 1, x: 2 }; // Error, duplicate property 'x'
    var q = x[z]; // Error, indexing by an object doesn't really work...
    var u = "hi".lenth; // Error, no property 'lenth' on string
    

    但是规范!

    一个常见的反驳是这样的

    “ECMAScript 规范定义 Math.max 将其参数强制转换为数字,因此调用 Math.max(someString, someOtherString) 应该是合法的”

    确实,ECMAScript 规范明确定义了在运行时发生的强制转换。然而,这个逻辑并没有给我们任何实际的洞察力。从表面上看,这个逻辑表明,因为所有参数在运行时都被强制编号,所以写应该是合法的

    var x = Math.max("hello", window.setTimeout, { });
    

    毕竟,这段代码确实有定义的行为!但这错过了树木的森林 - 对于任何合理的“正确”定义,这段代码是正确的显然令人难以置信。 TypeScript 的存在基于某些 JavaScript 代码不正确并且您想了解它的概念。

    规范描述了发生了什么这一事实并不能说明你是否正在编写一个正确程序。如果你吃了一块石头,医生可以清楚地描述你会发生什么,但这并不意味着石头就是食物。

    查看 ECMAScript 规范是一个类别错误,该规范旨在指定行为,并确定它实际上是描述正确代码的规范性文档。如果你愿意,你可以使用“规范定义的任何东西都应该没问题”的虚无主义理论,并使用从不发出类型警告的 TypeScript 变体。这种变体被广泛使用,被称为“JavaScript”。


    *:此规则的例外情况是降级,由于运行时的限制,可能存在可检测的差异,例如堆栈跟踪可能不同

    【讨论】:

    • 你写了“类型警告”并建议它们可以被忽略,但编译器用Error这个词报告它们,就像实际上阻止编译器发出代码的错误一样。如果 TS 编译器消息能够明确区分不兼容的类型和不建议兼容的类型,我个人会觉得非常有帮助。
    猜你喜欢
    • 2013-11-02
    • 2020-06-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-11
    相关资源
    最近更新 更多