快速参考

Primitive 原生数据类型#

JavaScript 有的 原生数据类型,Flow 都有

查看 内置类型 了解更多介绍和例子.

any#

any 是一种超集类型 同时 又是所有类型的子集

实际上用了 any 类型就不会检查了,如果能用别的类型就别用 any

用这种方式忽略检查是可行的,特别是在老项目中开始应用 Flow 类型的时候

It is also occasionally necessary to bypass the type checker. There are a (decreasing) number of JS idioms which Flow is not able to type statically. In these instances, it is practical and reasonable to use any. 有少数情况必须得忽略检查,Flow 无法对少数 JS 高级特性(草案)作静态类型分析, 这种情况就真的得用 any

查看 内置类型 了解更多 any 的特性

mixed#

mixed 是所有类型的超集

当你代码需要 动态判断类型 时,这种类型就很合适。 例如,你可以使用 mixed 类型来声明一个不确定类型的值,Flow 会确保你有足够的条件判断 来安全地使用这个值。

查看 内置类型 了解更多 mixed 的特性

Arrays#

这个类型用来描述 JavaScript 数组对象,并且描述数组中元素的类型

Indexing into an array with type Array<T> will always yield a value with type T. That is, Flow assumes arrays are dense and does not do bounds checking.

Array<T> 来声明一个数组后,数组的所有元素值都得是 T 类型的。 Flow 假设数组都是无限长度的,所以不作长度检测

let array: number[] = [1, 2, 3.14, 42];
let theAnswer: number = array[3]; // 42
let offTheEnd: number = array[100]; // No error

let array2: Array<string> = ["an alternate", "syntax", "for arrays"];

Tuples (元组)#

元组类型是一种特殊的数组类型,可以描述多个不同类型的元素

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
let tuple: [string, number, boolean] = ["foo", 0, true];

// Indexing into the array will return the type at a given index.
(tuple[0]: string);
(tuple[1]: string);

// Indexing into an statically unknown index will return a general type.
declare var unknownNumber: number;
// `void` is none of `string`, `number`, or `boolean`
(tuple[unknownNumber]: void);
(tuple[unknownNumber]: string|number|boolean); // OK

// Values written must be compatible with the type at that index.
tuple[1] = -1;
tuple[0] = false;
show Flow output hide Flow output
$> flow
1: let tuple: [string, number, boolean] = ["foo", 0, true];
               ^^^^^^ string. This type is incompatible with
10: (tuple[unknownNumber]: void);
                           ^^^^ undefined

1: let tuple: [string, number, boolean] = ["foo", 0, true];
                       ^^^^^^ number. This type is incompatible with
10: (tuple[unknownNumber]: void);
                           ^^^^ undefined

1: let tuple: [string, number, boolean] = ["foo", 0, true];
                       ^^^^^^ number. This type is incompatible with
5: (tuple[1]: string);
              ^^^^^^ string

1: let tuple: [string, number, boolean] = ["foo", 0, true];
                               ^^^^^^^ boolean. This type is incompatible with
10: (tuple[unknownNumber]: void);
                           ^^^^ undefined

15: tuple[0] = false;
               ^^^^^ boolean. This type is incompatible with
1: let tuple: [string, number, boolean] = ["foo", 0, true];
               ^^^^^^ string

查看 数组 了解更多

Objects#

这个类型用来描述对象值

1
2
3
4
5
let object: {foo: string, bar: number} = {foo: "foo", bar: 0};
(object.foo: string);

// Property writes must be compatible with the declared type.
object.bar = "bar";
show Flow output hide Flow output
$> flow
5: object.bar = "bar";
                ^^^^^ string. This type is incompatible with
1: let object: {foo: string, bar: number} = {foo: "foo", bar: 0};
                                  ^^^^^^ number

当对象作为映射表#

对象经常被用来当做查找表,映射表。所以 Map 类型这种情况更加贴切,Flow 支持这个方言。

let coolRating: {[id:string]: number} = {};
coolRating["sam"] = 10; // Yes, it's a 0-10 scale.

Callable 对象#

Functions are also objects, and may have other props. Flow models this as an object type with a callable property.

方法也是对象,也可以添加属性,于是 Flow 把它模拟成对象,并且有一个 callable 属性 就是例子中的 (x:number)

1
2
3
4
5
6
7
8
9
10
11
12
function makeCallable(): { (x: number): string; foo: number } {
  function callable(x) {
    return number.toFixed(2);
  }
  callable.foo = 123;
  return callable;
}

var callable = makeCallable();

var callableReturn: string = callable(Math.PI); // "3.14"
var callableFoo: number = callable.foo; // 123
show Flow output hide Flow output
$> flow
3:     return number.toFixed(2);
              ^^^^^^ identifier `number`. Could not resolve name

Object 类型#

Object 所有对象类型的超集. 这个类型的对象可以通过任意属性名访问, 返回的值具有 any 类型

any 一样,要慎用

var anyObject: Object = {};
anyObject.foo.bar.baz; // OK

查看 对象,了解更多

Functions#

函数可以有一个或多个参数,不一定要有返回值, 除了 “标准” 方法声明, Flow 还支持箭头方法, async 方法, 和 generator 方法.

function greatestCommonDivisor(a: number, b: number): number {
  if (!b) {
    return a;
  }

  return greatestCommonDivisor(b, a % b);
}

// Annotations included for example purposes only.
[1, 2, 3].map((num: number): number => num * 2)

async function getFriendNames(
  friendIDs: Promise<number[]>,
  getFriendName: (id: number) => Promise<string>,
): Promise<string[]> {
  var ids = await friendIDs;
  var names = await Promise.all(ids.map(getFriendName));
  return names;
}

function *infinity(): Generator<number,void,void> {
  var n = 0;
  while (true) {
    yield n++;
  }
}

Function 类型#

Function 所有方法类型的超集. 具有这个类型的方法,可以穿入任意多个参数, 然会值具有 any 类型

any 一样,要慎用

var anyFunction: Function = () => {};
anyFunction("foo", "bar").baz.quux; // OK

查看 方法 了解更多

#

定义一个类也就是定义了一个新类型,可以用来注解这个类的实例

class MyClass {
  foo: string;
  constructor(foo: string) {
    this.foo = foo;
  }
  bar(): string {
    return this.foo;
  }
}

var myInstance: MyClass = new MyClass("foo");
(myInstance.foo: string);
(myInstance.bar(): string);

接口#

类只是 Flow 名义上的类型,

如果两个类要进行匹配,他们就必须是通过 extends 继承,

而接口,通常用来描述结构相似的对象类型。

interface Fooable {
  foo(): string;
}

class AFoo {
  foo() { return "foo from A" };
}

class BFoo {
  foo() { return "foo from B" };
}

(new AFoo: Fooable);
(new BFoo: Fooable);

正式的类语法#

ES2015 这一标准,把过去用方法和原型模拟的面向对象 正式定义成 Class 系统, Flow 对它支持有限,不过 ES2015 类 的语法值得推荐。

function DietClass(foo: string) {
  this.foo = foo;
}

DietClass.prototype.bar = function() {
  return this.foo;
}

var myDietInstance: DietClass = new DietClass("foo");
(myDietInstance.foo: string);
(myDietInstance.bar(): string);

Class<T> 类型 (泛型类)#

如果把类名作为注解类型,只表示这个类的实例. T 表示实例类型, 而 Class<T> 表示类

var myClass: Class<MyClass> = MyClass;
var myInstance2 = new myClass("foo");

查看 了解更多

类型别名#

避免每次重复写复杂的类型,可以定义一个类型别名

type ObjectWithManyProperties = {
  foo: string,
  bar: number,
  baz: boolean,
  qux: (foo: string, bar: number) => boolean;
}

查看 类型别名 了解更多

泛型#

泛型可以在类型的基础上更加抽象。一个常见的例子就是容器类, 当你保存、传递和获取数据的时候,无须关注数据真正的类型

泛型对象可以使用别名类型来定义

type GenericObject<T> = { foo: T };
var numberObject: GenericObject<number> = { foo: 0 };
var stringObject: GenericObject<string> = { foo: "foo" };

泛型类型参数用来定义类

class GenericClass<T> {
  x: T;
  constructor(x: T) {
    this.x = x;
  }
}

var numberInstance: GenericClass<number> = new GenericClass(0);
var stringInstance: GenericClass<string> = new GenericClass("");

泛型类型参数用在方法上

function findMax<T>(arr: T[], compare: (a: T, b: T) => number) {
  var sorted = arr.sort(compare);
  return sorted[sorted.length - 1];
}

← Prev Next →

You can edit this page on GitHub and send us a pull request!