【问题标题】:Flow does not support certain JavaScript (ECMAScript) built-in methods, what do I do?Flow 不支持某些 JavaScript (ECMAScript) 内置方法,我该怎么办?
【发布时间】:2020-12-18 15:06:01
【问题描述】:

作为一名习惯于严格类型语言的嵌入式软件工程师,在用 JavaScript 编写实验性实用程序时,我不得不使用 Flow (https://flow.org)。

用 JS+Flow 编写代码大约 10 分钟后,Flow('flow-bin' 二进制文件)给了我以下错误:

无法调用 string.trim().replaceAll,因为字符串 [1] 中缺少属性 replaceAll(您的意思是替换吗?)。

关于以下(流注解)代码:

static sanitizeString(string : string) : string {
    return string.trim().replaceAll(/(?:\s+|\.+)/g, "");
}

Flow 告诉我它在(似乎是一个)“符号”定义文件中找不到(相当广泛实施的)string.prototype.replaceAll(...) 函数: tmp/flow/flowlib_1fa18dde633e97c7_501/core.js

这引出了问题:

在使用 ECMAScript 标准(或 考虑到浏览器实施 ECMAScript 的快节奏特性,有什么提案/草案?

我是否必须修改定义文件 (core.js) 才能解决此问题?

【问题讨论】:

  • replaceAll 可能已被“广泛实施”,但就实际引入的时间而言,它仍然是相当新的。 IIRC,它是一个 ES2020 的添加,它仍然是最近的。我对 Flow 不太熟悉,但也许您可以更改支持的版本。
  • 实际上我仔细检查了 - replaceAll 在今年获得批准,但计划添加到 ES2021 标准中。所以,你去吧。
  • @VLAZ 谢谢。似乎只有一个“core.js”作为 Flow 的“事实来源”(如果我错了,更熟悉 Flow 的读者可以纠正我)。转移到 TypeScript,因为 'esnext' 选项是最新的提案(正如 Samuli Hakoniemi 也在下面指出的那样)。至于 replaceAll(),在过去 6 个月里一直处于 TC39 流程的“最后阶段”(第 4 阶段):github.com/tc39/proposal-string-replaceall
  • 是的,它在 6 月获得批准,计划在标准 ES2021 的下一个版本中发布。所以,从技术上讲,它还不是一个标准。不过,它会是。

标签: javascript flowtype ecmascript-2021


【解决方案1】:

首先,我没有直接回答这个问题,但我会尽量详细说明这个问题。

但这很有趣。它确实引发了该错误:Flow Example

现在,它变得更有趣了,因为 TypeScript 抛出了同样的错误:TS Example

但是,TS 在错误消息中更加健壮:

“字符串”类型上不存在属性“replaceAll”。您需要更改目标库吗?尝试将 lib 编译器选项更改为“esnext”或更高版本。

因此,我建议您遵循该建议并切换流编译器以遵循不同的规则集(我猜是在 .flowconfig 中?)。

【讨论】:

  • 我切换到 TypeScript,因为 Flow 似乎没有提供关于使用哪个版本的 ECMAScript 的选项——似乎在“源代码”中真的只有一个“core.js”真理”为Flow。带有“esnext”的 TypeScript 似乎跟上了浏览器的步伐!
【解决方案2】:

我认为我们需要努力将这个问题与上下文联系起来,然后才能真正考虑回答。

Flow provides a base set of types 作为大多数用例的良好起点。这些会定期更新,但并不是真正有条理的过程的一部分。用户经常打开 PR 以使用他们感兴趣的部分来更新提供的 libdef,这可能是这些更新现在最常见的方式。对核心类型的更改通常非常简单,并且是很好的“第一个 PR”。还值得注意的是,flow 的传入 PR 比 typescript 少得多。

因此,实际情况最终是流提供的类型并不总是与最新规范的每个部分都是最新的。问题变成了,如何应对这种情况?

一种选择是停止使用提供的类型。 Flow 有一个配置选项:

no_flowlib (boolean)

Flow 具有内置库定义。将此设置为 true 将告诉 Flow 忽略内置库定义。

默认值为false

通过将其设置为true,我们将不再获得任何流提供的类型。这允许我们只使用我们指定的类型。一种常见的做法是将其切换为true,将流提供的类型复制到项目的本地 libdefs 中,并就地对其进行修改。这将使我们能够获得使用提供的类型的所有好处,同时还能够进行任何必要的修改。主要缺点是现在必须在升级流程版本时手动更新类型。

当然,另一种选择是只打开一个 PR。 Flow 发布相当迅速且可靠,并且对提供的 libdef 的更改通常会很快合并。

我不会评论这种事态的满意度是否令人满意,但如果有人面临这些担忧,那么希望这是您制定解决方案所需的全部信息。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-01-20
    • 2017-12-23
    • 2011-03-28
    • 1970-01-01
    • 2019-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多