边城

TypeScript 对决 Flow | Marius Schulz

边城 · 2017-01-16翻译 · 2099阅读 原文链接

TypeScript 和 Flow 类似,都关注同一个问题:JavaScript 没有静态类型。它们最终都能帮助你写出正确的代码。TypeScript 和 Flow 提供平衡转入静态类型的能力。它们使用相似的语法来说明类型,也使用相似的声明文件。

在微软和 Facebook,两个工具都在开发者社区中得到广泛使用。说到 TypeScript 和 Flow 的选择,总会有一些原因帮你做出决定。你所在的开发生态环境通常会对你的决定有很大影响,就像你之前接触静态类型系统一样。

在 TypeScript 和 Flow 之间选择

如果你在使用 Angular 2+,你会倾向于 TypeScript,因为它是在 Angular 社区中使用的主要语言。从另一方面来说,如果你在使用 React,你可能更喜欢 Flow,因为它更容易与 Babel 等你正在使用的基础工具整合。

你可能还要考虑一些其它因素。除了静态类型,TypeScript 还提供了强大的工作和语言服务以支持自动完成、代码导航和重构。而 Flow 需要你深入理解你的代码,甚至都不提供过程分析。

在对 TypeScript 和 Flow 的选择上,上面提到的都可能正常的理由。然而,我有时会听到人们提倡使用 Flow (同时返回 TypeScript),因为“它只是一个类型检查工具,而 TypeScript 是另一种语言”。这并不是正确的理由,我这就说明为什么。

它不只做类型检查

当你使用单独的类型说明,类型别名或者其它 Flow 特性,你就不再是写标准的 JavaScript。就是说,你不能在浏览器或像 Node 之类的其它 JavaScript 环境直接运行那段代码。这里有一个简单的 Flow 的例子,来源于其网站首页

// @flow
function bar(x): string {
  return x.length;
}
bar('Hello, world!');

你可以试试在浏览器的控制台运行这段代码。它不会工作!你会得到一个错误消息,比如 Unexpected token :,因为解析器遇到了返回类型申明。如果想让这段代码正确运行,就必须移除类型说明。

这就是 TypeScript 和 Flow 的不同:TypeScript 实现了类型检查,同时实现了转译工具用来生成纯粹的 JavaScript 。Flow 只进行类型检查,并依赖 Babelflow-remove-types或者其它工具来移除类型说明。

现在让我们澄清这件事:选择 TypeScript 还是 Flow 都不是问题,你都不会写纯粹的 JavaScript。你是在使用非标准的语句特性。这么说来,TypeScript 和 Flow 都是与 JavaScript 不同的语言。TypeScript 承认这一事实并主动采用 .ts 文件扩展名,而不是标准的 .js 扩展名。

把类型申明放在注释中

据说有一种写标准 JavaScript 来使用 Flow 的方法。可以把类型申明放在注释中,Flow 仍然能够分析他们。这里有一个以前的例子:

// @flow
function bar(x) /* : string */ {
  return x.length;
}
bar('Hello, world!');

现在这是完全有效的 JavaScript 代码,你可以在不进行预编译的情况下在任何 JavaScript 环境执行。不过我不喜欢这个方法,我认为附加的句法干扰着代码,使之难以阅读。此外,注释并不是类型系统该待的地方。

小结

TypeScript 和 Flow 都是伟大的产品。它们帮助你写正确的代码。你应该选择适合团队需要的那一个。不管如何,请不要说 Flow 不是另一种语言而 TypeScript 是 —— 只要你不是非常严谨地在注释中书写类型申明,你写的就不是标准的 JavaScript。

相关文章