手机版

流 一个新的Javascript静态类型检查器

时间:2021-09-20 来源:互联网 编辑:宝哥软件园 浏览:

今天,我们很兴奋地发布了Flow的早期版本,这是一个新的Javascript静态类型检查器。Flow在Javascript中加入静态类型检查,提高开发效率和代码质量。更具体地说,静态类型检查提供的好处就像早期错误检查,它可以帮助您发现一些只能在运行时发现的错误,以及代码智能感知,它将有助于代码维护、搜索、重构和优化。

我们设计流程的所有功能都建立在现有的Javascript规范上。因为Flow在后台积极工作,所以额外的编译开销非常小。Flow不需要开发人员编写代码——。她使用复杂的算法来分析熟悉的代码风格。

Flow还处于起步阶段,但我们已经在脸书使用了它。我们希望您能在自己的项目中愉快地使用它,并期待您的反馈。你可以先去flowtype.org看看。

从整体上看

脸书喜欢Javascript;它速度快,表现力强,无处不在,是打造产品的绝佳语言。同时,因为没有困扰开发人员的静态类型。bug很难发现(例如崩溃的原因隐藏得很深),代码维护就像一场噩梦(例如,在不知道所有依赖关系的情况下重构是有风险的)。Flow提高了速度和效率,提升了开发人员使用Javascript时的生成效率。

在Javascript之上添加一层静态系统并不容易。Javascript的构造块极具表现力,简单的类型系统无法准确地组合出合适的语义。为了支持不同的Javascript编程范式和习惯,Flow引入了数据流和控制流等分析技术,这些技术通常用于在编译过程中提取语义。然后利用提取的信息和高级类型原理来推断类型。当然,只有强静态类型分析是不够的。——的JavaScript代码库会非常大,这就要求类型检查必须快如闪电,以免中断开发者的编辑-运行过程。流按模块执行分析,所有类型都限制在模块边界内。这最终形成了一个高度并行和增量的检查架构,类似于Hack。这使得类型检查快速响应,即使是数百万行代码。

流量类型检查是可选的——。您不需要一次执行全部检查。然而,Flow背后的设计是基于这样的假设:大多数Javascript代码类型都是隐式静态类型;虽然类型可能不会出现在代码中的每一个地方,但是它们以一种可以根据代码的正确性来推断的形式存在于开发人员的脑海中。一旦可能,Flow会推断出这些类型,这意味着它可以在不更改代码的情况下找到类型错误。另一方面,一些Javascript代码,如框架中存在的代码,大量使用反射,这使得静态类型推断非常困难。对于这种自然和动态的代码,类型检查充满了错误,所以Flow提供了给这种代码增加信任并继续。这种设计已经被脸书的大量Javascript代码库验证:大多数代码无法通过隐式静态类型检查条目,这允许开发人员在不添加注释的情况下检查代码类型错误。

这使得Flow从根本上不同于其他的Javascript类型系统(比如TypeScript)。通过弱化大多数JavaScript代码是动态输入的假设,开发人员自己表达了哪些代码应该是静态类型。一般来说,这种设计会导致检查覆盖率较低:检测到的类型错误较少,工具不够高效。但是,在某些情况下是合理的。一般来说,如果没有大量的额外努力,这种设计无法为实际开发提供足够的帮助。尽管如此,Flow允许您轻松获得这种弱化的类型检查,这对于现有代码非常有用。

要解释这种差异,请查看以下示例:

only function workonnumbers(x){ return x * 10;} only work onnumbers(' Hello,world!');Flow可以找到这个错误(试图将数字和字符串相乘),但是另一个更保守的分析需要显式标记x的类型,在这个玩具般的例子中,没有任何努力,但是在庞大的代码库中几乎没有人这样做。Flow可以在不添加注释的情况下找到此错误。当然,前提是开发者想这么做。

类型系统

流式系统实现了许多预期的功能。支持标准的基本类型(数字、字符串、布尔值),除了一些特殊情况,禁止类型之间的隐式转换。还支持函数、对象和数组等类型。类型可以是多态的。

您可能会感到惊讶,流并不认为null和undefined是上述任何类型。这两种类型的可能性有很多,这些类型的使用必须建立在合理检验的保护基础上。还支持其他组合类型(如字符串|数字),这种用法也需要加以保护。了解动态检查在缩小流量类型范围时的影响。

让我们用一个例子来描述如何处理空值。以下程序总是在运行时崩溃,但一般类型的系统会认为它没有问题:

函数长度(x){ return x . length;} var total=length(' Hello ')length(null);流程将在编译时发现此错误,并指示x可以为null(不应访问length属性)。另外,Flow知道这个程序的控制流程,所以简单的修改就可以使这个程序类型正确:

函数长度(x) { if (x!==null){ return x . length;} else { return 0;} } var total=length(' Hello ')length(null);Flow还理解JavaScript的复杂对象模型:构造函数、方法、原型及其动态扩展和绑定。我们试图支持复杂的类型操作,比如绑定对象、提取键等等。我们希望这些特性能够在未来为框架指定特定的类型。

类型错误通常被报告为定义和实际值之间的不兼容:例如,函数调用的参数不足,对象不包含要访问的属性,或者字符串被用作数字。

最后,Flow支持动态类型(any),可以绕过类型系统检查:例如,any可以用来指示静态分析无法准确判断和报告错误的位置(通常使用反射)。此外,如果Flow在弱模式下遇到上述类型,并且没有注释类型,它将自动假设任何类型。

扩展性

为了扩展,Flow根据模块与其他模块的依赖关系以及其他模块提供的类型接口,分别对每个模块进行检查。要生成类型接口,流可能需要对模块边界进行注释。

在后台运行的持久服务器上,Flow维护整个代码库的语义信息。首先,Flow会对整个代码进行一次分析,然后当一系列文件发生变化时(可能是单个文件发生了变化或者是分支发生了切换),服务器会因为类型关联,对变化后的文件和其他相关文件的语义信息进行增量更新。这样,当开发人员试图获取类型错误时,它们已经在服务器上了,并且响应几乎是立即的。这种服务器架构建立在与Hack相同的技术之上。

和睦相处

Flow致力于支持最新的JavaScript标准。目前,它已经支持各种ES6特性,如去结构化、类、扩展对象、可选函数参数和核心API扩展(如Map、Set、Promise,以及对象、数组和数学上的新方法)。其他功能(尤其是模块)正在开发中。该流程支持CommonJS/Node.js规范的模块。

var Hello=react . create class({ render : function(){ return div Hello { this . props . name }/div;}});如果您在JSX上使用的类名是错误的,Flow会发现这个问题:

React.render(,);此外,如果您使用反应。PropTypes规范在React类中,您可以对JSX的属性进行静态类型检查:

var Hello=React . create class({ proptypes : { name : React。PropTypes.string.isRequired }.});流将发现Hello/缺少属性的错误,或者Hello name={ 42 }/属性类型的错误。

有关支持React的更多详细信息,请参见文档。

源代码开放的

流代码大部分是用OCaml实现的。代码库正在积极更新,并将在未来几个月迅速发展。除了在全脸书的数据代码库中运行之外,我们希望Flow的分析引擎可以用来构建类似的语言工具,无论是JavaScript还是其他语言。如果你想加入,请告诉我们!

好了,全新的Javascript静态类型检查器Flow的全部内容就先介绍到这里了,以后会不断更新,敬请关注!

版权声明:流 一个新的Javascript静态类型检查器是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。

相关文章推荐