Maybe Types(我稱他為判斷類型)
如果你想使用一個(gè)非number類型的參數(shù)疾瓮,可以如下定義笛坦,當(dāng)然判斷類型是可以接受null 和 undefined的參數(shù)丧失。
function acceptsMaybeNumber(value: ?number) {
// ...
}
acceptsMaybeNumber(42); // Works!
acceptsMaybeNumber(); // Works!
acceptsMaybeNumber(undefined); // Works!
acceptsMaybeNumber(null); // Works!
acceptsMaybeNumber("42"); // Error!
Maybe Types 進(jìn)階
假設(shè)我們有個(gè) Maybe Types ?number, 如果我們想使用該值作為一個(gè)數(shù)字恕汇,我們需要首先檢查它是不是null或undefined阀坏。
// @flow
function acceptsMaybeNumber(value: ?number) {
if (value !== null && value !== undefined) {
return value * 2;
}
}
您可以使用單個(gè)!=null檢查簡(jiǎn)化針對(duì)null和nudefined的兩種檢查波势,這兩種檢查都可以完成翎朱。
// @flow
function acceptsMaybeNumber(value: ?number) {
if (value != null) {
return value * 2;
}
}
您也可以將其翻轉(zhuǎn),并在使用前檢查以確保該值具有一種類型的數(shù)字尺铣。
// @flow
function acceptsMaybeNumber(value: ?number) {
if (typeof value === 'number') {
return value * 2;
}
}
Variable Types
// @flow
const foo /* : number */ = 1;
const bar: number = 2;
當(dāng)你給變量聲明類型的時(shí)候拴曲,你如果將它重新賦值,必須和他聲明的值是一樣的凛忿。
// @flow
let foo: number = 1;
foo = 2; // Works!
// $ExpectError
foo = "3"; // Error!
Reassigning variables(重新分配變量)
默認(rèn)情況下澈灼,當(dāng)您重新分配一個(gè)變量時(shí),F(xiàn)low將為它提供所有可能的賦值類型
let foo = 42;
if (Math.random()) foo = true;
if (Math.random()) foo = "hello";
let isOneOf: number | boolean | string = foo; // Works!
有時(shí)侄非,在重新分配后蕉汪,flow能夠(肯定地)找出變量的類型流译。在這種情況下,F(xiàn)low將給出已知的類型者疤。
// @flow
let foo = 42;
let isNumber: number = foo; // Works!
foo = true;
let isBoolean: boolean = foo; // Works!
foo = "hello";
let isString: string = foo; // Works!
if語句福澡、函數(shù)和其他有條件運(yùn)行的代碼都可以阻止Flow精確地計(jì)算出類型是什么。
// @flow
let foo = 42;
function mutate() {
foo = true;
foo = "hello";
}
mutate();
// $ExpectError
let isString: string = foo; // Error!
Function Types(函數(shù)類型)
函數(shù)有兩個(gè)地方需要定義類型驹马,一個(gè)是參數(shù)革砸,一個(gè)是返回值。
// @flow
function concat(a: string, b: string): string {
return a + b;
}
concat("foo", "bar"); // Works!
// $ExpectError
concat(true, false); // Error!
即使不用類型注釋糯累,有些類型也會(huì)自動(dòng)檢測(cè)
// @flow
function concat(a, b) {
return a + b;
}
concat("foo", "bar"); // Works!
// $ExpectError
concat(true, false); // Error!
有時(shí)候 Flow 會(huì)創(chuàng)建一種你比較希望的類型算利。
// @flow
function concat(a, b) {
return a + b;
}
concat("foo", "bar"); // Works!
concat(1, 2); // Works!
函數(shù)語法
有三種形式的函數(shù),每種形式都有各自略有不同的語法泳姐。
函數(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ù)類型
(str: string, bool?: boolean, ...nums: Array<number>) => void
省略參數(shù)名
(string, boolean | void, Array<number>) => void
您可以將這些函數(shù)類型用于諸如回調(diào)之類的操作效拭。
function method(param1: string, param2: boolean) {
// ...
}
可選參數(shù)
您還可以通過在參數(shù)名稱后面和冒號(hào):之前添加一個(gè)問號(hào)來?yè)碛锌蛇x參數(shù):
function method(optionalValue?: string) {
// ...
}
可選參數(shù)可以不傳或者undefined或匹配的類型。但他們不會(huì)接受NULL胖秒。
// @flow
function method(optionalValue?: string) {
// ...
}
method(); // Works.
method(undefined); // Works.
method("string"); // Works.
// $ExpectError
method(null); // Error!
Rest 參數(shù)
在參數(shù)列表 末尾 末尾 末尾 手機(jī)參數(shù)數(shù)組的參數(shù)缎患, 用 ... 來表示
function method(...args: Array<number>) {
// ...
}
你可以將任意多的參數(shù)傳遞到 rest 參數(shù)中
// @flow
function method(...args: Array<number>) {
// ...
}
method(); // Works.
method(1); // Works.
method(1, 2); // Works.
method(1, 2, 3); // Works.
需要注意的是,如果你向rest參數(shù)添加類型注釋阎肝,則必須是數(shù)組類型的挤渔。
返回值
函數(shù)返回還可以使用冒號(hào):添加類型,然后在參數(shù)列表后添加類型风题。如下:
function method(): number {
// ...
}
返回類型確保函數(shù)的每個(gè)分支返回相同的類型判导。這樣可以防止您在某些情況下意外地不返回值。
// @flow
// $ExpectError
function method(): boolean {
if (Math.random() > 0.5) {
return true;
}
}
this
JavaScript中的每個(gè)函數(shù)都可以使用一個(gè)名為 this 的特殊上下文來調(diào)用沛硅。您可以使用所需的任何上下文調(diào)用函數(shù)眼刃。
function method() {
return this;
}
var num: number = method.call(42);
// $ExpectError
var str: string = method.call(42);
Predicate函數(shù) (額...謂詞函數(shù))
有時(shí),您可能希望將條件從if語句移動(dòng)到函數(shù)中:
function concat(a: ?string, b: ?string): string {
if (a && b) {
return a + b;
}
return '';
}
但是稽鞭,F(xiàn)low將在下面的代碼中會(huì)出錯(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 '';
}
您可以通過使truthy成為謂詞函數(shù)來解決這個(gè)問題鸟整,可以使用 %check 注釋,如下所示:
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á)式(即不支持局部變量聲明)朦蕴。但也可以調(diào)用謂詞函數(shù)中的其他謂詞函數(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([]);
Callable Objects 可調(diào)用對(duì)象(本人對(duì)這個(gè)也不是特別理解弟头,往有大神指出)
可以輸入可調(diào)用對(duì)象吩抓,例如:
type CallableObj = {
(number, number): number,
bar: string
};
function add(x, y) {
return x + y;
}
// $ExpectError
(add: CallableObj);
add.bar = "hello world";
(add: CallableObj);
Function Type
有時(shí)候參數(shù)要接受任意函數(shù)的類型:
function method(func: () => mixed) {
// ...
}
如果你需要選擇退出類型檢測(cè)程序,同時(shí)你有不想用any類型,你可以用function類型
function method(func: Function) {
func(1, 2); // Works.
func("1", "2"); // Works.
func({}, []); // Works.
}
method(function(a: number, b: number) {
// ...
});