随着JavaScript项目变得越来越复杂,开发者开发了新的工具和语言来提高代码质量和工作流程。
除了单元测试,TypeScript和Flow等静态类型检查器正在成为专业开发团队的标准。无论项目大小,使代码更易于理解并在开发阶段捕获错误的好处已被证明是非常有用的。
在没有使用类型检查工具的情况下处理大型JavaScript代码库会让你感到头痛,特别是那些在运行时才会发现的错误会产生很多,但是当你采用了类型检查,或者使用了TypeScript之后,你会发现这些类型的错误大大减少,不仅开发效率得到提高,最重要的是代码的质量得到了极大提升。
在本文中,主要介绍这两个工具,并说明它们的工作方式。并且演示如何将TypeScript和Flow集成到React应用程序中。
TypeScript
TypeScript是微软开发的一种编程语言。它是开源的,并得到了一个庞大而活跃的社区的支持
TypeScript是JavaScript的类型化超集,可编译为纯JavaScript。
“类型化”一词表示TypeScript要求程序员声明给定变量的数据类型。
“超集”一词表示TypeScript允许程序员使用JavaScript提供的所有功能,以及一些额外的功能,如接口,泛型,装饰器等。
下图展示了TypeScript运行方式的高级概述。编译器接收TypeScript文件(.ts或.tsx),然后将它们“转换”为可由浏览器运行的有效JavaScript代码。
我们来看一些用TypeScript编写的简单代码:
functiongetName(person:IPerson):void{console.log(person);}interfaceIPerson{name:stringage:number}getName({"name":"john",age:20});getName({age:23})//Argumentoftype{age:number;}isnotassignabletoparameteroftypeIPerson.
正如我们在上面的代码块中看到的,我们声明了一个函数,该函数接受一个具有两个属性的对象,分别是字符串和数字类型的名称和年龄。调用该函数时,TypeScript会检查提供的对象的类型是否正确,如果类型不正确,就会像在调用第二个函数的时候代码将无法编译并抛出错误。
Flow
与TypeScript相比,Flow并不是一种编程语言,它被叫作JavaScript的静态类型检查器,类似于我们经常使用的ESLint,它是由Facebook开发的。
我们可以通过向常规JavaScript文件添加特殊注释来使用Flow,指示我们期望的类型,或者我们可以让工具推断出期望的类型并在发现任何错误时警告我们。
我们来看看以下Flow官方文档的案例:
//
flowfunctionsquare(n){returnn*n;//Error!}square("2");
注意到上面代码的第一行了吗?为了让工具知道它必须检查哪些文件,我们通过添加注释
flow在每个要包含在Flow监控过程中的文件中。
使用Flow,您不必更改文件的扩展名,而是继续在带注释的文件.js和.jsx文件中编写普通的JavaScript。
如果我们保留上面的代码,JavaScript引擎会因为注释而抛出错误;
因此,作为额外的步骤,我们必须在最后编译代码之前删除所有注释。
当然我们可以使用Babel或者flow-remove-types等工具来清除它们。
Flow与TypeScript与React的集成
一个标准的React应用程序
创建React应用程序的最简单方法是使用create-react-app工具。
我们将创建两个相同的React应用程序,一个用于测试TypeScript,另一个用于测试Flow。
首先,让我们通过创建一个没有任何类型检查的React应用程序来看看这个工具的实现:
npxcreate-react-appdemo-app
React启用TypeScript
如果我们从头开始,我们可以像这样使用–template标志来创建一个支持TypeScript的React应用程序:
npxcreate-react-appreact-ts--templatetypescript
对于一个新项目这是一个最佳的办法,如果我们想要在现有的项目中启用react的话,我们需要做下面的操作。
yarnaddtypescript
types/nodetypes/reacttypes/react-domtypes/jest
接下来,我们将现有的.js和.jsx文件重命名为.ts和.tsx。
重启我们的开发服务器之后,你会发现项目目录中多了一个tsconfig.json文件,这个文件是typescript的配置文件,你可以对它进行一些偏好配置。
然后我们创建一个React组件
importReactfrom"react";interfaceProps{items:Item[]}exportinterfaceItem{id:number,name:string}functionItemList(propsrops){constlistItems=props.items.map(item=item.name);returnlistItems;}exportdefaultItemList;
TypeScript允许我们使用接口声明我们期望的对象类型。
在这里,我们声明了Props接口,它有一个属性item,一个Item类型的对象数组——另一个接口有两个属性,一个number类型的id和一个string类型的name,两者都是必需的。
然后,我们通过添加注解props:Props说我们的函数组件ItemsList的props参数是一个Props类型的对象。
让我们ItemsList在我们的App.tsx文件中实现这个组件并声明一个名为items的常量,就像一个包含虚拟对象的数组一样,看看TypeScript是如何反应的:
您可以看到显示了一个错误,指出Item必须包含id和name属性。如果我们此时尝试运行应用程序,TypeScript可以避免我们产生错误。
现在让我们删除我们的项目const的类型,看看这个错误是否消失:即使我们没有声明项目const应该是typeItem[],TypeScript也足够聪明,可以发现在我们的ItemsList组件中使用它是不安全的。
现在让我们通过向组件添加两个适当的记录来解决这个问题:
constitems:Item[]=[{id:1,name:"One"},{id:2,name:"Two"}];
我们现在看到应用程序编译并成功执行:通过引入TypeScript,我们避免了运行潜在错误的代码,同时还通过显式声明整个应用程序中使用的类型使代码本身更具可读性。
React启用Flow
yarnaddflow-binnpmrunflowinit
然后我们创建和之前一样的ItemsList组件。
importReactfromreact;functionItemsList(props){constlistItems=props.items.map(item=item.name);return(listItems);}exportdefaultItemsList;
运行yarnflow会出现错误,接下来我们添加一些类型。
//
flowimportReactfromreact;typeItem={id:number,name:string}typeProps={items:Item[]}functionItemsList(props
rops){constlistItems=props.items.map(item=item.name);return(listItems);}exportdefaultItemsList;
重新运行yarnflow,将不会提示任何错误。
每次要使用Flow检查文件时,我们都必须运行相同的命令。对于使用VSCode的用户,可以使用FlowLanguageSupport在每次保存后自动执行Flow检查。其他IDE将具有等效功能,只需搜索即可找到与您的环境相关的实现。
TypeScript与Flow的优缺点
TypeScript优点:
不仅仅是一个类型检查器:TypeScript向JavaScript添加了额外的数据结构,如Enums,来自其他语言的开发人员可能缺少这些数据结构。它还具有接口、装饰器和其他使其更加健壮的功能——使开发人员能够编写极其全面的代码。这些功能在大型和企业风格的项目中尤其强大。
由Microsoft开发:TypeScript正在接收定期更新并将继续发展。可以肯定地说,在快速发展的JavaScript生态系统中,TypeScript的寿命将比大多数其他“趋势”更长。
大型社区:TypeScript拥有一个庞大而活跃的社区,他们愿意为它的开发做出贡献,并通过回答他们的问题或编写有用的教程来帮助他人。除了官方文档之外,您还可以找到大量有关TypeScript主题的非官方资源。
TypeScript缺点:
陡峭的学习曲线:TypeScript一开始可能是严格且无情的,让开发人员望而却步。它比Flow更难和更复杂,因为它更健壮,并且被认为是一种编程语言(或至少是JavaScript的“超集”)。TypeScript也感觉像是一种全有或全无的方法,这会使事情复杂化并减慢具有大量依赖项的大型项目的开发速度。
大量重复代码:有人认为TypeScript沉淀了大量模板代码,这会增加开发时间并使文件更难理解。在这种情况下,代码极简主义者可能更喜欢轻量级Flow(或根本不进行类型检查)。
Flow优点:
易用性:Flow比TypeScript更宽容,可作为对JavaScript中静态类型的更温和的介绍。启动和运行速度更快,而且由于其按文件选择加入的方法,将Flow添加到现有项目中也可能更容易。
由Facebook开发:开发React的公司,因此您可以确定这两种工具完全兼容并且可以一起使用。
Flow缺点:
更小的社区:Flow拥有一个更小、更不活跃的社区,这意味着那些试图学习如何使用它并调试可能出现的问题的人可用的资源更少。这也可能意味着它在支持和添加功能方面的未来比TypeScript更加不确定。
不那么健壮:Flow可以很好地进行类型检查,但仅此而已。TypeScript可能更适合具有较长支持范围的更多企业项目,同时考虑到开发人员可以在此类项目中使用其更高级的功能。Flow可能是更精简项目的更好选择,或者作为将类型检查引入现有项目的一种方式,而不会太痛苦。由您决定哪种工具最适合您的项目和环境。
结论
TypeScript和Flow之间有明显的区别。在功能方面,TypeScript更健壮,而Flow只是一个类型检查器。
尽管Flow是由Facebook创建的,但是对于同公司开发的React框架来说,并没有特别优待之处,毕竟它最初的目的就不是作为react的附属工具,而是作为一个通用项目管理工具。
对于喜欢轻量级,喜欢快速上手的人来说,flow是一个不错的选择,你可以非常快速地入门并使用它。
而如果你在开发一个大型项目,那么typescript应该是你最佳的选择,它庞大的社区让它的发展异常迅速,主流的框架源码都采用了typescript进行开发足以说明问题。