Flow函数类型(Function Types)

2018-01-25  本文已影响0人  vincent_z

函数类型(Function Types)

函数有两个应用类型检查的地方:参数(输入)和返回值(输出)。

// @flow
function concat(a: string, b: string): string {
  return a + b;
}

concat("foo", "bar"); // Works!
// $ExpectError
concat(true, false);  // Error!

使用类型推导可以省略类型定义

// @flow
function concat(a, b) {
  return a + b;
}

concat("foo", "bar"); // Works!
// $ExpectError
concat(true, false);  // Error!

函数语法

函数申明

function method(str, bool, ...nums) {
  // ...
}

function method(str: string, bool?: boolean, ...nums: Array<number>): void {
  // ...
}

箭头函数

let method = (str, bool, ...nums) => {
  // ...
};

let method = (str: string, bool?: boolean, ...nums: Array<number>): void => {
  // ...
};

函数类型

在这里你可以看到写入函数的类型的语法

(str: string, bool?: boolean, ...nums: Array<number>) => void

你也可以选择省略参数名称。

(string, boolean | void, Array<number>) => void

你可能会在回调函数中使用这些函数类型。

function method(callback: (error: Error | null, value: string | null) => void) {
  // ...
}

函数参数

函数参数添加类型的方式是在参数名称后面添加:

function method(param1: string, param2: boolean) {
  // ...
}

可选函数参数

函数添加可选参数的方式是在参数的名字和冒号:之前添加?

function method(optionalValue?: string) {
  // ...
}

可选参数可以接收匹配类型,undefined或被省略,但不能接收nul

// @flow
function method(optionalValue?: string) {
  // ...
}

method();          // Works.
method(undefined); // Works.
method("string");  // Works.
// $ExpectError
method(null);      // Error!

Rest参数

JavaScript支持在参数列表的末尾接收剩余参数或数组参数。他们面前有一个...

function method(...args: Array<number>) {
  // ...
}
// @flow
function method(...args: Array<number>) {
  // ...
}

method();        // Works.
method(1);       // Works.
method(1, 2);    // Works.
method(1, 2, 3); // Works.

注意 rest参数必须是Array类型

函数返回

函数返回也可以使用:类型

function method(): number {
  // ...
}

返回类型确保函数的每个分支都返回相同的类型。这可以防止你在特定条件下意外不返回值。

// @flow
// $ExpectError
function method(): boolean {
  if (Math.random() > 0.5) {
    return true;
  }
}

函数 this

JavaScript中的每个函数都可以被一个名为`this`的特殊上下文调用。你可以用你想要的任何上下文来调用一个函数。

在Flow中,你不需要键入注释,Flow将检查你调用该函数的任何上下文。
function method() {
  return this;
}

var num: number = method.call(42);
// $ExpectError
var str: string = method.call(42);

谓词函数

谓词函数是一个判断式,一个返回bool值的函数或者仿函数:P:X→{true,false},称为X上的谓词。

有时你会想从if语句中移动条件到一个函数中,但是,Flow将在下面的代码中标记一个错误:

function truthy(a, b): boolean {
  return a && b;
}

function concat(a: ?string, b: ?string): string {
  if (truthy(a, b)) {
    // $ExpectError
    return a + b;
  }
  return '';
}

你可以通过使用%checks注解来修复这个问题,方法如下:

function truthy(a, b): boolean %checks {
  return !!a && !!b;
}

function concat(a: ?string, b: ?string): string {
  if (truthy(a, b)) {
    return a + b;
  }
  return '';
}

这些谓词函数的主体必须是表达式(即不支持局部变量声明)。但是可以在谓词函数中调用其他的谓词函数。例如:

function isString(y): %checks {
  return typeof y === "string";
}

function isNumber(y): %checks {
  return typeof y === "number";
}

function isNumberOrString(y): %checks {
  return isString(y) || isNumber(y);
}

function foo(x): string | number {
  if (isNumberOrString(x)) {
    return x + x;
  } else {
    return x.length; // no error, because Flow infers that x can only be an array
  }
}

foo('a');
foo(5);
foo([]);

函数类型

如果需要函数接收任意类型的函数,对于那些你应该写()=>混合的类型:

function method(func: () => mixed) {
  // ...
}

但是,如果你想要退出类型检查,并且不使用any,那么可以使Function类型。 Function类型是不安全的,应该避免。

function method(func: Function) {
  func(1, 2);     // Works.
  func("1", "2"); // Works.
  func({}, []);   // Works.
}

method(function(a: number, b: number) {
  // ...
});

Function类型等同于any类型

上一篇下一篇

猜你喜欢

热点阅读