TypeScript vs Flow

2,821 阅读8分钟

本文源于翻译 TypeScript vs Flow

TypeScript

如果你是一名前端开发人员,就可能听说过 TypeScript ,甚至使用过它。 TypeScript 是 JavaScript 的类型化超集,是由微软开发并维护的一门编程语言。它的目的是启用强类型来增强 JavaScript 在大型应用的开发能力。 TypeScript 言如其名。

一句话概述,可以使用静态类型。就像我们在很多服务端语言那样,比如 java , C# 。静态类型具有很多优点,比如编译器能更好的识别正在编写的代码。更准确的发现错误,优化编译过程,确保我们定义的每个变量都能传递正确的值。

TypeScript 封装了 ECMAScript 语法,这意味着我们可以使用 class, module, const, let 和所有来自 ECMAScript 的语法,但不仅仅于此。它还能进一步提供那些原生 ECMAScript 并没有的功能,比如泛型,装饰器等等。它有一个相当 强大的 社区,如果想使用具有静态类型的 JavaScript ,我们能从中获得很好的支持。更方便的是,它通过创建类型 声明文件 来规范代码,而无需修改代码。

Flow

Flow 是由 Facebook 开发,官方文档上定义它为 静态类型检查器 ,而 不是 一种编程语言。由于 JavaScript 是动态类型语言,在程序输出方面可能存在很多问题,开发者往往会得到意料之外的结果。举个例子,我们可以定义一个变量,其初始值设置成字符串类型,有意或者 无意 (通常是无意,这就是为什么为粗体)为其赋一个整数值,此时编译器不会报错。这时候,Flow 的作用就体现出来了。 Flow 可以通过注释很简单的集成进 JavaScript 项目。我们要做的是在安装和配置 Flow 之后,添加一行代码。

// @flow

就在 JavaScript 文件的开头,没有比这更简单的了。

另一个好处是, Flow 可以被逐渐的采用,因为它很容易从我们代码中添加或者删除,而且不用破坏任何东西。如果我们只想对一部分代码开启类型检查, Flow 非常方便。

对比

下面的列表,我将尝试对比两者的不同和相似之处

与 JavaScript 关联度

TypeScriptFlow
一种编程语言,JavaScript 的类型化超集。旨在提供 JavaScript 中缺少的功能,如静态类型一个基于我们现有 JS 代码的 JavaScript 类型检查器。旨在快速和精确的代码检查和分析。

使用它的好处

TypeScriptFlow
主要好处是提供了静态类型。除此之外,它还提供了很多有用的工具,如代码重构、自动补齐、d代码导航。它有很棒的 IDE 支持。与 VSCode 的集成使该编辑器十分受欢迎。主要好处是提供静态类型。此外,它给我们提供强大的程序分析能力,帮助我们更好的分析和控制代码。

功能特征

TypeScriptFlow
编译时类型检查(如果类型不正确,它将不允许编译);类型注释;枚举;装饰器;泛型;接口;命名空间;模块; JSX; 声明文件; JS 文件类型检查(例如 @ts-check )静态类型检查;类型注释;泛型;接口;代码修改后立刻重新检查(实时反馈); 精确; 快速; 方便使用; 对 JavaScript 模式具有深刻的理解;

优点

TypeScriptFlow
流行的框架支持(Vue、React、Angular);强大的社区;声明文件覆盖大多数 JS 库;强大的 IDE 支持;可以让 JS 文件启用类型检查而不修改它们(声明文件);支持任何 JS 文件;易于集成;对 JS 模式有深刻理解;不是编程语言;实时反馈;快速; 精确

缺点

TypeScriptFlow
另一种编程语言;难以整合进现有的 JS 项目较小的社区;并不太关注类型;更少的 IDE 支持

主流框架支持度

TypeScriptFlow
支持所有主流框架,Vue、Angular 和 React,我们可以把 TypeScript 与它们任何一个一起使用React 内置且支持度很高,当我们使用 React 时, Flow 可能是更好的选择。

社区支持

社区支持对任何一个开源项目都特别重要。使用者对项目的 支持度 直接 决定了它的存在 。如果我们对此进行统计,就能得出结论,发展时间更长、更完善的 TypeScript 有一个更强大的社区。另一方面,Flow 更年轻,因此缺乏社区支持(尽管社区支持度不仅仅取决于产品年龄)。

TypeScript 享有 Angular 2+ 的全面支持,这意味着 TypeScript 发展在一个已经存在的生态系统之上。强大的社区让我们不用担心无法在项目中使用一些库,因为往往已经有人为该库编写了 TS 的声明文件。此外,有一个对它支持度非常高的 IDE (VSCode),我相信它的流行归功于 TypeScript 。它的性能很棒,至少我在项目中没有遇到任何问题。

对于 Flow,就有了不同的情况。这是一个年轻的项目,支持它的社区较小,但我们不能否认它在官方 GitHub 上有相当多的星星。较小的社区意味着较少的库定义,因此我们应该小心并确保我们的项目不要引入(以后也不会引入)不受支持的库。这很重要,如果作为开发者缺乏相关经验,这就会变的非常棘手,因此我们在为项目选择工具包时需要格外小心。很棒的是 React 对 Flow 有强大的内置支持,这意味着只要 React 保持受欢迎程度并且集成度保持强劲,我相信 Flow 将拥有一个安全的未来。

语法对比

在下面的对比中,我们将比较一些常见的语法。更多有关的详细信息,请查看此仓库

可选类型(可以为空)

TypeScript

let myVariable: string | null | undefined

Flow

在Flow中,我们可以这样做

let myVariable: : ?string

// the above statement is equivalent to:

let myVariable: : string | null | void

可选参数

TypeScript

我们可以自定义一个名称来定义一个可选参数,该名称需要在冒号(:)之前加上问号 (?)。

function fullName(firstName: string, lastName?: string) {
  return lastName ? firstName + ' ' + lastName : firstName
}

任何可选参数都只能在必传参数的后面。如果我们想让 firstName 参数是可选的,而不是 lastName 参数,我们需要更改函数中参数的顺序,将 firstName 放在参数列表的最后一个。

Flow

Flow 情况就有点不同了。问号 (?) 在冒号 (:) 之后:

function fullName(firstName: string, lastName: ?string) {
  return lastName ? firstName + ' ' + lastName : firstName
}

类型断言

TypeScript

let a: any = "1";
let b = a as number;

// 值本身也可以被断言

(1 + 1) as number;

Flow

let a: any = '1'
let b = (a: number)

// 值本身也可以被断言

;(1 + 1: number)

类型断言可以使用在表达式可以出现的任何地方。

模块

在模块(文件)之间共享类型通常很有用。在下列两个文件中,我们可以从一个文件中导出类型别名、接口和类,然后在另一个文件中导入。

TypeScript

class MyClass {}

export default MyClass
export { MyClass }
export { MyClass as someName }

Import:

// 单个导入
import { MyClass } from 'MyClass'

// 导入整个模块

import * as MyClass from 'MyClass'

Flow

导出

export default class MyClass {}
export type MyObject = {
  /* ... */
}
export interface MyInterface {
  /* ... */
}

导入

import type MyClass, { MyObject, MyInterface }

在 Flow 中,当导入一个类时,我们需要使用 type 关键字。

哪个更适合 React 的项目?

TypeScript 和 Flow 的对比即将结束时,让我们思考下 React 对它们的支持以及它们与这个框架的集成程度。考虑到 Flow 和 React 同一家公司(Facebook)创造的,我们可以期望它是基于 React 项目的正确工具。我们离真相不远了。在这里,Flow 可以充分发挥其潜力。它对 React 有强大的内置支持。如果你是 create-react-app 命令的粉丝,你会很高兴听到,它默认支持 Flow。您需要做的就是安装 Flow 并通过运行 flow init 创建一个 .flowconfig 文件。查看指南 .

另一方面,TypeScript 过去对 React 的支持稍差,但现在不同。现在它内置支持 JSX 。使用此功能,需要使用 tsx 扩展名命名我们的文件,并在 tsconfig 文件中启用 JSX 选项。这意味着糟糕的 React 支持已经成为过去。查看官方 jsx 指南.

结论

我认为上述两个工具各有其特点。这可能是个人偏好问题,你喜欢的,可能我不喜欢,我们很自然地在工作中选择不同的工具。就我个人而言,我的大部分项目中都使用了 TypeScript,对此我很满意。如果您寻求与 React 进行更深入的集成,并且您认为 TypeScript 缺少这部分,那么 Flow 就是你更好的选择。如果你认为这篇文章对你有帮助,请在 Twitter 上分享或关注我 :)

资源

进一步阅读

查看 这篇文章 其中我对 React、Vue 和 PlazarJS 进行了 Hello World 比较