React - 使用 TypeScript vs Flow vs?

Posted

技术标签:

【中文标题】React - 使用 TypeScript vs Flow vs?【英文标题】:React - using TypeScript vs Flow vs? 【发布时间】:2016-08-20 17:07:53 【问题描述】:

我目前正在学习 React,并且我认为我非常了解它。然而,关于开发健壮的 React 应用程序,有一件事情一直困扰着我——开发人员使用哪些工具来进行静态类型检查?

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

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

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

我还发现了两篇关于使用React + Flow 和React + TypeScript 的文章。作者陈述了他在使用这两个选项时遇到的一些问题,并得出结论认为 TypeScript 是“目前最好的选择”(2015 年 11 月),特别是因为 Flow 项目存在很多问题并且从 Facebook 收到的开发人员活动很少。他还提到它与 Babel 不兼容?

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

2017 年 9 月更新:

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

TypeScript 直到今天仍然很难用。问题在于 JavaScript 世界发展得太快了,以至于 TypeScript 一直落后。考虑使用新的 ES7 stage 3 特性?不,你不能。希望获得某些库的最新版本的类型提示?等一两个月,也许更久…… Flow已经走了很长一段路,改进了很多,它可以捕捉到一些TS无法捕捉到的东西。最重要的是,它终于可以在 Windows 上运行了。此外,还有很棒的 VS Code 插件(不知道为什么它只有 3/5 的评分)。它与 React Native 100% 兼容,TypeScript 还不到 50%。 大多数时候,您根本不需要类型。所有额外的输入很少是值得的。 JS 是一种动态类型的语言,克服它:)

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

2019 年 2 月更新:

我认为上述建议已过时,不再适用。三个原因:

React Hooks 在这里。它们使您的代码的类型检查变得更加容易。 In most situations, no additional code is needed. TypeScript 的类型推断得到了改进。 TypeScript 拥有比 Flow 更大的社区。 Even yarn,Facebook 的包经理,is moving away from Flow, to TypeScript。

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

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

【问题讨论】:

你也可以只使用纯 JavaScript,React 为你提供了 propTypes,这样你就可以确保 props 是正确的类型并在需要时传递。 是的,我知道 propTypes。但是,这只能部分解决问题 - 在视图层中(如果我没记错的话?)。商店和操作中的代码呢?我也想在那里进行静态输入。 blog.wolksoftware.com/working-with-react-and-typescript 似乎有一些关于使用 typescript 和 react 以及您需要使用的不同扩展的很好的文档 感谢文章的链接!我过去见过它,但我认为作者过得太快了(尤其是对于像我这样刚开始使用 React 的人)。不过,第二次看这篇文章时,我发现了一篇优秀文章的链接,如果你想像我一样使用 React + TypeScript 组合,我strongly recommend reading it。 感谢您在发布 3 年后继续更新。值得注意的是,现在使用 "$create-react-app --typescript" 支持 ts 【参考方案1】:

我要开始这个答案,说我从未使用过 Flow,所以我不能说太多。但是,我们在工作中使用 React 和 TypeScript,效果很好。

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

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

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

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

【讨论】:

【参考方案2】:

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

http://michalzalecki.com/typescript-vs-flow/ (2016-07-15) https://blog.wearewizards.io/flow-and-typescript-part-2-typescript (2015-11-20) https://blog.wearewizards.io/flow-and-typescript-part-1-flow (2015-11-13)

流程设计人员采用的方法感觉更实用,具有更好的类型推断和更好的 null 方法。但是,TypeScript 有更好的社区支持,尤其是在通过 http://definitelytyped.org/ 为第三方库引入类型方面,这对于让类型在所有代码中流动以实现最大的类型安全非常重要。 TypeScript 由 Microsoft 创建,它在编写编译器和向有利方向发展技术方面拥有丰富的历史 - 这里值得注意的是 C# 以及它们已经添加非空类型的事实(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,
        ...
    

【讨论】:

【参考方案3】:

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

TypeScript 使用代码生成来输出 JavaScript,而在 Flow 中,注释被简单地剥离,没有这样的代码生成。过去,微软推广 TypeScript 的人曾经说过代码生成是“本地文件”的(我不记得使用的确切术语)。这应该提供一种安慰,即 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 已经赢得了胜利,是时候继续前进了。

【讨论】:

“一家专门从事不道德和有问题的技术实践的公司”——而 Facebook 没有? :P 这篇文章有强烈的固执己见(有充分的理由说明为什么“vs”问题在 SO 上是题外话)。至于扩展,流类型的 .js 不是有效的 JS,所以我不确定在这里保持相同的扩展是否是一件好事(更不用说 TS 是 Babel+Flow 工具链的替代品,而不仅仅是 Flow)。 更强大 - 值得澄清。 Angular 与新项目并不真正相关 - 怎么会这样?仅仅因为你在 React 船上并不意味着每个人都是。这些框架确实不同,有长处和短处,获得了很大的动力,并且一直在 SO 上正面交锋。【参考方案4】:

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

使用 Flow,initial setup 可以在 vanilla js 上运行静态分析(它推断多种类型):
function square(n) 
  return n * n; // Error!


square("2");
使用 TypeScript 有一个 migration effort,没有它只有 some vanilla js static analysis: noImplicitReturns 可防止您忘记在函数结束时返回。 noFallthroughCasesInSwitch 如果您不想忘记 switch 块中 case 之间的 break 语句,这将很有帮助。 TypeScript 还会警告无法访问的代码和标签,您可以分别使用 allowUnreachableCode 和 allowUnusedLabels 禁用它们。

流动的更多好处

Flow 的 Comment Types 和 Error Suppression 进一步支持 vanilla js,允许您通过合法的 js cmets 逐步合并类型检查,这些 cmets 注释类型或抑制您可能尚未准备好进行的特定检查。评论类型在 TypeScript 中的 feature request 已经有一段时间了,直到最近才有一个 PR(参见上一个链接)。

流动的缺点

也就是说,Flow 的所有简单性都以一些漂亮的 complex configuration 为代价,并带有一些烦人的警告,比如它是如何使用 type checks 3rd party libraries 等的。有人可以给出的关于 Flow 的最佳建议:尝试交叉引用任何东西您在他们的文档中阅读,因为它已经过时并且在某些情况下可能会有点误导。

【讨论】:

以上是关于React - 使用 TypeScript vs Flow vs?的主要内容,如果未能解决你的问题,请参考以下文章

VS Code Prettier - Code Formatter Extension 不适用于使用 Typescript 模板的 Create-React-App

VS Code 或 Chrome 开发工具:调试 NPM Workspaces (monorepo) TypeScript + React 代码

如何使VS2015/2017的TypeScript支持React

使来自 react-intl 的 FormattedMessage 中的 id 继承自自定义 TypeScript 接口以启用 VS IntelliSense 和类型检查

Flow vs. Typescript

使用 Typescript(TSX 文件)将道具传递给 React 中的子组件