函數(shù)類型(Function Types)
函數(shù)有兩個(gè)應(yīng)用類型檢查的地方:參數(shù)(輸入)和返回值(輸出)。
// @flow
function concat(a: string, b: string): string {
return a + b;
}
concat("foo", "bar"); // Works!
// $ExpectError
concat(true, false); // Error!
使用類型推導(dǎo)可以省略類型定義
// @flow
function concat(a, b) {
return a + b;
}
concat("foo", "bar"); // Works!
// $ExpectError
concat(true, false); // Error!
函數(shù)語法
函數(shù)申明
function method(str, bool, ...nums) {
// ...
}
function method(str: string, bool?: boolean, ...nums: Array<number>): void {
// ...
}
箭頭函數(shù)
let method = (str, bool, ...nums) => {
// ...
};
let method = (str: string, bool?: boolean, ...nums: Array<number>): void => {
// ...
};
函數(shù)類型
在這里你可以看到寫入函數(shù)的類型的語法
(str: string, bool?: boolean, ...nums: Array<number>) => void
你也可以選擇省略參數(shù)名稱。
(string, boolean | void, Array<number>) => void
你可能會(huì)在回調(diào)函數(shù)中使用這些函數(shù)類型。
function method(callback: (error: Error | null, value: string | null) => void) {
// ...
}
函數(shù)參數(shù)
函數(shù)參數(shù)添加類型的方式是在參數(shù)名稱后面添加:。
function method(param1: string, param2: boolean) {
// ...
}
可選函數(shù)參數(shù)
函數(shù)添加可選參數(shù)的方式是在參數(shù)的名字和冒號(hào):之前添加?。
function method(optionalValue?: string) {
// ...
}
可選參數(shù)可以接收匹配類型,undefined或被省略,但不能接收nul
// @flow
function method(optionalValue?: string) {
// ...
}
method(); // Works.
method(undefined); // Works.
method("string"); // Works.
// $ExpectError
method(null); // Error!
Rest參數(shù)
JavaScript支持在參數(shù)列表的末尾接收剩余參數(shù)或數(shù)組參數(shù)。他們面前有一個(gè)...。
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參數(shù)必須是Array類型
函數(shù)返回
函數(shù)返回也可以使用:類型。
function method(): number {
// ...
}
返回類型確保函數(shù)的每個(gè)分支都返回相同的類型。這可以防止你在特定條件下意外不返回值。
// @flow
// $ExpectError
function method(): boolean {
if (Math.random() > 0.5) {
return true;
}
}
函數(shù) this
JavaScript中的每個(gè)函數(shù)都可以被一個(gè)名為`this`的特殊上下文調(diào)用。你可以用你想要的任何上下文來調(diào)用一個(gè)函數(shù)。
在Flow中,你不需要鍵入注釋,F(xiàn)low將檢查你調(diào)用該函數(shù)的任何上下文。
function method() {
return this;
}
var num: number = method.call(42);
// $ExpectError
var str: string = method.call(42);
謂詞函數(shù)
謂詞函數(shù)是一個(gè)判斷式,一個(gè)返回bool值的函數(shù)或者仿函數(shù):P:X→{true,false},稱為X上的謂詞。
有時(shí)你會(huì)想從if語句中移動(dòng)條件到一個(gè)函數(shù)中,但是,F(xiàn)low將在下面的代碼中標(biāo)記一個(gè)錯(cuò)誤:
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注解來修復(fù)這個(gè)問題,方法如下:
function truthy(a, b): boolean %checks {
return !!a && !!b;
}
function concat(a: ?string, b: ?string): string {
if (truthy(a, b)) {
return a + b;
}
return '';
}
這些謂詞函數(shù)的主體必須是表達(dá)式(即不支持局部變量聲明)。但是可以在謂詞函數(shù)中調(diào)用其他的謂詞函數(shù)。例如:
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([]);
函數(shù)類型
如果需要函數(shù)接收任意類型的函數(shù),對(duì)于那些你應(yīng)該寫()=>混合的類型:
function method(func: () => mixed) {
// ...
}
但是,如果你想要退出類型檢查,并且不使用any,那么可以使Function類型。 Function類型是不安全的,應(yīng)該避免。
function method(func: Function) {
func(1, 2); // Works.
func("1", "2"); // Works.
func({}, []); // Works.
}
method(function(a: number, b: number) {
// ...
});
Function類型等同于any類型