React——使用 TypeScript vs Flow vs?

React - using TypeScript vs Flow vs?

我目前正在学习 React,我认为我已经很好地理解了它。然而,关于开发健壮的 React 应用程序,有一件事一直困扰着我——开发人员使用什么工具进行静态类型检查?

我非常喜欢 TypeScript。我认为它大大减少了开发 JavaScript 应用程序的痛苦,这要归功于类型检查和其他简洁的功能。 Visual Studio Code 还提供了非常好的代码完成功能。我知道我可以通过使用 typings + DenifitelyTyped.

让它与 React 一起工作

问题是,关于使用 React + TypeScript 的教程并不多。似乎也没有很多关于使用此组合进行开发的文章。另一方面,很多人似乎都在使用 Flow,这是一个由 Facebook 支持的项目(我猜他们也使用它)。

我设法找到了 discussion on Reddit 关于采用 React + TypeScript / React + Flow 方式的优缺点。然而,对我来说,它似乎已经过时了,因为它现在已经有 10 个月大了。我认为从那以后发生了很多变化。

我还找到了两篇关于使用 React + Flow and React + TypeScript 的文章。作者陈述了他在使用这两个选项时 运行 遇到的一些问题,并得出结论认为 TypeScript 是 "the best bet right now"(2015 年 11 月),特别是因为 Flow 项目有很多问题并且开发人员很少 activity来自脸书。他还提到它与 Babel 配合得不好?

所以,我想问题是:使用 React + TypeScript 组合是否安全,或者我 运行 会遇到一些困难吗?流量呢?我应该检查其他一些类似的工具吗?您会推荐哪种方法?

2017 年 9 月更新:

有一年多日常使用 TypeScript 的经验,也玩过一段时间的 Flow,我得出以下结论:

TL;DR:如果您打算使用任何类型检查器,我建议使用 Flow。

2019 年 2 月更新:

我认为上面的建议已经过时并且不再相关。三个原因:

所以,我认为 TypeScript 在 2019 年是一个比 Flow 更务实的选择。

至于是否值得使用任何类型检查器,我认为这取决于项目大小。小项目可能不需要它。

我要开始这个回答说我从来没有使用过Flow,所以我不能说太多。但是,我们在工作中使用了 React 和 TypeScript,而且效果很好。

我们拥有我想您已经知道的所有好处,例如重构、类型安全、自动完成等。

当然,就我所见,Flow 语法比 TypeScript 更清晰,但您可以使用 TypeScript 逐步添加您的类型。我认为,这更多是品味问题。有些人更喜欢显式输入代码,而另一些人更喜欢输入更少并具有更强的类型推断。

关于,我认为 TypeScript 是安全的技术,Microsoft 正在推广该语言 (there will be a version 2 soon),Angular 也在使用它,并且有很多 Angular 开发人员。即使在 SO 上,TypeScript 标签也有超过 4000 名关注者,而且很少有未回答的问题。

TypeScript 的大问题,至少对我们来说是,有时我们决定使用没有类型定义的组件或库,因此我们必须自己创建它们。但我想,这是回馈社区的一种方式。

我刚刚问了自己同样的问题(尽管不是 React),发现以下文章对评估两者很有用:

流程设计者采用的方法感觉更实用,具有更好的类型推断和更好的空值方法。但是,TypeScript 有更好的社区支持,尤其是在通过 http://definitelytyped.org/ which is important for having types flow through all your code for maximum type safety. TypeScript is created by Microsoft which has a rich history in writing compilers and evolving the technology in favorable directions - notable here is C# and the fact that they are already adding non-null types (2016-07-11): https://blogs.msdn.microsoft.com/typescript/2016/07/11/announcing-typescript-2-0-beta/

为第三方库引入类型方面

TypeScript 似乎是今天更安全的选择。

对于那些在现有代码库中尝试 TypeScript 的人,我发现我的 tsconfig.json 文件中的以下设置非常有助于让 TypeScript 与 JavaScript 很好地共存(允许转换一个文件在一次):

{
    "compilerOptions": {
        "allowJs": true,
        "isolatedModules": true,
        ...
    }
}

在我的 React 开发中,我设置了相当复杂的 Babel / Webpack / Flow / Mocha 工具链,并且从未遇到过任何 Flow 问题。需要一些努力来设置所有内容(Webpack 起初可能令人生畏),但之后,它就可以正常工作了。 Flow 绝对是必经之路,因为它是一种范围更窄、更专注的技术,因此更有可能与其他工具配合使用。相比之下,TypeScript 试图不仅仅是一种类型推断/静态类型检查工具,因此它带来了额外的包袱和假设。因此,React 是一种专门的工具,可以很好地完成一件事,而 TypeScript 实际上是一种建立在 JavaScript 之上的语言。为确保 Microsoft 能说明问题,TypeScript 文件通常也有不同的扩展名(.ts 而不是 .js),因为您现在使用的是不同的语言,明白吗?

TypeScript 使用代码生成来吐出 JavaScript 而在 Flow 中,注释被简单地剥离,没有代码生成本身。以前,微软推广 TypeScript 的人曾声明,代码生成是 "file-local"(我不记得使用的确切术语)。这本应让人放心,TypeScript 编译器并没有做任何太神奇的事情。无论如何,我再也找不到该声明显着显示了。使用 Flow,你不需要这样的保证,因为你用普通的 JavaScript(或你为 Babel 配置的任何 ECMA 版本)编写,并且注释,就像我说的,只是被剥离。

更不用说 TypeScript 来自一家专门从事不道德和有问题的技术实践的公司(我不排除 TypeScript 最终可能会成为所有拥抱-扩展-灭绝策略之母)。我们不要忘记 Microsoft did everything in their power to cause Javascript to fail,因为他们(正确地,即使为时已晚)预见到它对他们糟糕的操作系统和臃肿的办公套件所代表的威胁,并且仍然代表着。

此外,上次我费心评估 TypeScript(大约 2015 年)时,Flow 的类型系统 强大得多 并且在源代码中逐步甚至偶尔应用它要容易得多.为了集成第三方库,我使用 flowtyped 并且我很少需要用我自己的定义来补充在那里找到的库。

最后,Angular 使用 TypeScript 的事实绝对没有任何意义,因为 Angular 与新项目无关。 React 赢得了胜利,是时候继续前进了。

如果你想要类型检查但更愿意保持普通的旧 javascript(以避免编译,或为了可移植性等),这是两者之间的一个重要区别(对于 React 或一般而言):

  • 使用 Flow,initial setup 可以 运行 vanilla js 的静态分析(它 推断 多种类型):
    function square(n) {
      return n * n; // Error!
    }
    
    square("2");
    
  • 有 TypeScript 的 migration effort and only some vanilla js static analysis 没有它:
    • noImplicitReturns 这可以防止您在函数末尾忘记 return。
    • noFallthroughCasesInSwitch 如果您永远不想忘记 switch 块中 case 之间的 break 语句,这将很有帮助。
    • TypeScript 还会对无法访问的代码和标签发出警告,您可以分别使用 allowUnreachableCode 和 allowUnusedLabels 禁用它们。

流动的更多好处

Flow 在 TypeScript 中的 Comment Types and Error Suppression take support for vanilla js a step further, by allowing you to gradually incorporate type checks through legal js comments that annotate the type or suppress specific checks you might not be ready for yet. Comment types have been a feature request 已经有一段时间了,直到最近才有了它的 PR(参见之前的 link)。

流动的缺点

也就是说,Flow 的所有简单性确实是以一些漂亮的 complex configuration with some annoying caveats, like how it type checks 3rd party libraries 等为代价的。关于 Flow 的最佳建议:尝试交叉引用您在他们的文档中阅读的任何内容,因为它是已过时,在某些情况下可能会产生误导。