Flow 不支持某些 JavaScript (ECMAScript) 内置方法,我该怎么办?

Flow does not support certain JavaScript (ECMAScript) built-in methods, what do I do?

作为一名习惯了严格类型语言的嵌入式软件工程师,在 JavaScript.

中编写实验实用程序时,我不得不使用 Flow (https://flow.org)

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

Cannot call string.trim().replaceAll because property replaceAll (did you mean replace?) is missing in String [1].

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

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

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

这引出了问题:

Flow 用户在使用由ECMAScript 标准( proposals/drafts 就此而言,考虑到浏览器实施 ECMAScript 的快节奏特性)?

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

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

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

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

不过,TS更健壮,报错信息:

Property 'replaceAll' does not exist on type 'string'. Do you need to change your target library? Try changing the lib compiler option to 'esnext' or later.

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

我认为在真正考虑回答这个问题之前,我们需要努力对这个问题进行一些语境化。

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

所以实际情况最终是流提供的类型并不总是与最新规范的每一个部分保持同步。问题变成了,人们应该如何处理这种情况?

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

no_flowlib (boolean)

Flow has builtin library definitions. Setting this to true will tell Flow to ignore the builtin library definitions.

The default value is false.

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

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

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