TypeScript 自动大括号插入(ABI)是不理想的

dsf9zpds  于 2个月前  发布在  TypeScript
关注(0)|答案(4)|浏览(55)

TypeScript版本: 3.7-beta
搜索词: 自动大括号插入 ABI语法错误
代码:

function a() {
    "Automatic Brace Insertion! (ABI)";

预期行为:

输入在语法上无效,因此emit应该失败,无论noEmitOnError的状态如何。其他无法解析的输入形式已经这样做了,例如function a(

实际行为:

在生成的JS代码中插入了一个关闭括号。

function a() {
    "Automatic Brace Insertion! (ABI)";
}

这意味着不使用noEmitOnError的用户会默默地将无效代码转换为有效代码。我可以确认有人将其发布到生产环境。

**Playground链接:**ABI Playground链接
相关问题:#34870 , #34871 , Lazy Twitter report

我建议根据设计目标7(保留所有JavaScript代码的运行时行为)和设计非目标7(引入可能令用户惊讶的行为)修复此bug。

**标语:**如果括号不适合,就不应该发出。

avwztpqn

avwztpqn1#

据我所知,这至少在一定程度上是一个设计限制,因为TS内部没有足够区分语法错误和语义错误,以便仅在前者的情况下选择性地阻止发出。AST结构中的括号是隐式的,这意味着在解析OP中的代码后,AST中有足够的信息来发出——事实证明如此。
有关上述设计限制的更多背景见此处的评论:#28868(评论)
特别是:
我们曾经对语义错误和语法错误(后者会阻止发出)有所区分;但出于各种效率原因,我们将这些错误检查移到了一个单独的阶段,这种区分变得不可维持。

mbskvtky

mbskvtky2#

如果括号不合适,你就不能发出。

😆

anauzrmj

anauzrmj3#

我非常赞同这个精神。在解析过程中,语法错误曾经是均匀产生的,而在检查过程中,语义错误会产生。但随着时间的推移,我们允许某些不符合语法规则的东西被解析,然后在后续的检查过程中产生错误 - 在编辑器中这样做有时是非常有利的,可以提高完成体验。
这里的工作在技术上是直接的(将每个错误诊断标记为emit-blocking或非emit-blocking),但问题在于是否值得维护和存储这些数据。我们也存在一些分歧,例如:

interface X extends { }

显然是一个语法错误,但有人认为它不应该阻止emit吗?或者也许它是语法上有效的,但由于extends子句的长度为0,存在语义错误?这种区别并不总是100.0%明显。或者也许类型位置上的语法错误根本不重要,因为它们无论如何都会被擦除?

ycl3bljg

ycl3bljg4#

是的,我能理解这项工作的回报可能看起来对于付出的努力/维护来说较低。我不会争论这是一项高优先级的任务,考虑到解决方法是使用 "noEmitOnError"
也许我们可以通过将这个问题的范围限制在基本的明显错误集合中来降低努力,例如不平衡的大括号/括号。

相关问题