跳至主要内容

版本-0.14.0

我们注意到,并非所有人都会痴迷地检查 GitHub 以获取 Flow 版本。这让我们感到惊讶,但我们也希望支持这些用户。因此,我们将从本版本开始,在博客上发布每个 Flow 版本的公告。

所以,Flow v0.14.0 发布了!查看 变更日志 以获取所有更改的规范列表。

宣布不相交联合

有时,程序需要同时处理不同类型的数据,其中数据的形状可能因代码正在查看的数据类型而异。这种类型的编程在函数式编程语言中非常普遍,以至于几乎所有此类语言都提供了一种方法来

  • 通过一组不相交的 case 来指定此类数据,这些 case 由“标签”区分,每个标签都与不同的属性“记录”相关联。(这些描述称为“不相交联合”或“变体”类型。)
  • 通过检查标签,然后直接访问关联的属性记录,对这种数据进行 case 分析。(进行这种 case 分析的常用方法是模式匹配。)

分析或转换此类数据的程序示例包括从处理抽象语法树的编译器到可能返回异常值的运算,以及介于两者之间的更多内容!

从 Flow 0.13.1 开始,现在可以在 JavaScript 中以类型安全的方式使用这种风格进行编程。您可以定义对象类型的不相交联合,并通过切换这些对象类型中某个公共属性(称为“哨兵”)的值来对该类型的对象进行 case 分析。

Flow 的不相交联合语法如下所示

type BinaryTree =
{ kind: "leaf", value: number } |
{ kind: "branch", left: BinaryTree, right: BinaryTree }

function sumLeaves(tree: BinaryTree): number {
if (tree.kind === "leaf") {
return tree.value;
} else {
return sumLeaves(tree.left) + sumLeaves(tree.right);
}
}

宣布有界多态性

从 Flow 0.5.0 开始,您可以定义具有类型参数界限的多态函数和类。这对于编写需要对类型参数进行一些约束的函数和类非常有用。Flow 的有界多态性语法如下所示

class BagOfBones<T: Bone> { ... }
function eat<T: Food>(meal: T): Indigestion<T> { ... }

问题

考虑以下代码,它在 Flow 中定义了一个多态函数

function fooBad<T>(obj: T): T {
console.log(Math.abs(obj.x));
return obj;
}

此代码不会(也不应该!)进行类型检查。并非所有值 obj: T 都具有属性 x,更不用说具有属性 x,该属性是 number,这是 Math.abs() 强加的额外要求。

宣布 Flow 注释

从 Flow 0.4.0 开始,您可以将 Flow 特定的语法放在特殊的注释中。如果您使用这些特殊的注释,则无需在运行代码之前转换 Flow 特定的语法。虽然我们强烈建议您在没有特殊注释的情况下编写代码,但此功能将帮助那些无法将 Flow 剥离转换融入其设置中的人。这是我们 最受欢迎的功能之一,希望它能使更多人使用 Flow!

此功能引入了 3 个特殊的注释:/*:/*::/*flow-include。Flow 将读取这些特殊注释内的代码,并将代码视为特殊注释标记不存在。这些特殊注释是有效的 JavaScript 块注释,因此您的 JavaScript 引擎将忽略注释内的代码。

宣布导入类型

从 Flow 0.3.0 开始,现在可以从另一个模块导入类型。因此,例如,如果您只是为了在类型注释中引用而导入一个类,您现在可以使用新的 import type 语法来执行此操作。

动机

您是否遇到过这种情况

// @flow

// Post-transformation lint error: Unused variable 'URI'
import URI from "URI";

// But if you delete the require you get a Flow error:
// identifier URI - Unknown global name
module.exports = function(x: URI): URI {
return x;
}

现在您有了解决方案!为了解决这个问题(并着眼于不久的将来使用 ES6 模块语法),我们添加了新的 import type 语法。使用 import type,您可以传达您的真实意图——您想要导入类的类型,而不是实际的类本身。

宣布类型转换

从版本 0.3.0 开始,Flow 支持类型转换表达式。

类型转换表达式是为任何 JavaScript 表达式添加类型注释的简单方法。以下是一些类型转换的示例

(1 + 1 : number);
var a = { name: (null: ?string) };
([1, 'a', true]: Array<mixed>).map(fn);

对于任何 JavaScript 表达式 <expr> 和任何 Flow 类型 <type>,您可以编写

(<expr> : <type>)

注意:括号是必需的。