使用Flow來檢測你的JS

最近在一篇文章上看見了關(guān)于Flow的介紹,覺得它很不錯通贞,雖然之前在項目中使用Typescript已經(jīng)很順手了朗若,再使用Flow感覺有點累贅了,但多學(xué)點總是沒錯的昌罩。

簡介

JS作為一種腳本語言是沒有類型檢測的哭懈,這個特點有時候用著很爽,但當(dāng)你在一個較大的項目中的時候茎用,就會發(fā)現(xiàn)這其實是一件挺糟糕的事情遣总,因為和你協(xié)作的程序員往往不太清楚你所寫的代碼到底哪種類型才是正確的睬罗,而且代碼重構(gòu)的時候也很麻煩。于是基于這個需求有了Typescript和Flow的產(chǎn)生旭斥,今天這里主要介紹Flow容达。

安裝

因為筆者一直使用的是WebStorm,WebStorm內(nèi)部對Flow就有一定的支持垂券,所以如果你也使用WebStorm的話會方便很多董饰。

yarn add --dev flow-bin babel-cli babel-preset-flow

在安裝了上述的包之后,創(chuàng)建 .babelrc 文件:

{
  "presets": ["flow"]
}

設(shè)置WebStorm

通過 File>Settings>Languages&Frameworks>JavaScript 如下圖所示設(shè)置圆米,F(xiàn)low package可以選擇你項目下的flow-bin卒暂,當(dāng)然你也可以全局安裝flow-bin,然后在這里設(shè)置后就可以在每個項目中都使用Flow了 娄帖。

Flow-Settings

flow不能直接在node或瀏覽器環(huán)境中使用也祠,所以我們必須用babel編譯后才能使用:


Snipaste_2018-01-15_23-54-48.png

現(xiàn)在環(huán)境已經(jīng)快配好了,只剩最后一步近速,將一個此項目初始化為一個Flow項目:

yarn run flow init
Snipaste_2018-01-16_00-00-14.png

現(xiàn)在當(dāng)我們在項目中使用Flow時WebStorm可以給出智能的提示了诈嘿。

使用

類型

最新的 ECMAScript 標(biāo)準(zhǔn)定義了 7 種數(shù)據(jù)類型:

在Flow中也是使用這幾種類型作為標(biāo)注:

使用原始類型:

// @flow
function method(x: number, y: string, z: boolean) {
  // ...
}

method(3.14, "hello", true);

使用對象類型:

// @flow
function method(x: Number, y: String, z: Boolean) {
  // ...
}

method(new Number(42), new String("world"), new Boolean(false));

這里需要注意的是大小寫,小寫的 number 是原始類型削葱,而大寫的 Number 是JavaScript的構(gòu)造函數(shù)奖亚,是對象類型的。

Boolean

在Flow中析砸,默認(rèn)并不會轉(zhuǎn)換類型昔字,如果你需要轉(zhuǎn)換類型請使用顯示或隱式轉(zhuǎn)換,例如:

// @flow
function acceptsBoolean(value: boolean) {
  // ...
}

acceptsBoolean(true);  // Works!
acceptsBoolean(false); // Works!
acceptsBoolean("foo"); // Error!
acceptsBoolean(Boolean("foo")); // Works!
acceptsBoolean(!!("foo")); // Works!

Number

// @flow
function acceptsNumber(value: number) {
  // ...
}

acceptsNumber(42);       // Works!
acceptsNumber(3.14);     // Works!
acceptsNumber(NaN);      // Works!
acceptsNumber(Infinity); // Works!
acceptsNumber("foo");    // Error!

null和void

JavaScript兼有 nullundefined首繁。Flow將這些視為單獨的類型:nullvoid(void表示undefined類型)

// @flow
function acceptsNull(value: null) {
  /* ... */
}

function acceptsUndefined(value: void) {
  /* ... */
}

acceptsNull(null);      // Works!
acceptsNull(undefined); // Error!
acceptsUndefined(null);      // Error!
acceptsUndefined(undefined); // Works!

也許類型

也許類型是用于可選值的地方作郭,你可以通過在類型前添加一個問號(如 ?string 或者 ?number)來創(chuàng)建它們。

除了問號 ? 后跟著的類型弦疮,也許類型也可以是 null 或者 void 類型夹攒。

// @flow
function acceptsMaybeString(value: ?string) {
  // ...
}

acceptsMaybeString("bar");     // Works!
acceptsMaybeString(undefined); // Works!
acceptsMaybeString(null);      // Works!
acceptsMaybeString();          // Works!

可選的對象屬性

對象類型可以具有可選屬性,問號 ? 位于屬性名稱后面胁塞。

{ propertyName?: string }

除了它們的設(shè)定值類型之外咏尝,這些可選屬性也可以被 void 完全省略。但是啸罢,他們不能 null编检。

// @flow
function acceptsObject(value: { foo?: string }) {
  // ...
}

acceptsObject({ foo: "bar" }); // Works!
acceptsObject({ foo: undefined }); // Works!
acceptsObject({ foo: null }); // Error!
acceptsObject({}); // Works!

可選的函數(shù)參數(shù)

函數(shù)可以具有可選參數(shù),其中問號 ? 出現(xiàn)在參數(shù)名稱后面伺糠。同樣蒙谓,該參數(shù)不能為 null

// @flow
function acceptsOptionalString(value?: string) {
  // ...
}

acceptsOptionalString("bar");     // Works!
acceptsOptionalString(undefined); // Works!
acceptsOptionalString(null);      // Error!
acceptsOptionalString();          // Works!

文字類型

文字類型使用一個具體的值作為類型:

function foo(value: 2) {}

foo(2); // Work!
foo(3); // Error!
foo('2'); // Error!

您可以使用這些類型的原始值:

  • 布爾人: truefalse
  • 數(shù)字:像 423.14
  • 字符串:像 "foo""bar"
// @flow
function getColor(name: "success" | "warning" | "danger") {
  switch (name) {
    case "success" : return "green";
    case "warning" : return "yellow";
    case "danger"  : return "red";
  }
}

getColor("success"); // Works!
getColor("danger");  // Works!
// $ExpectError
getColor("error");   // Error!

混合類型 mixed

有時候我們并不能確定需要的值到底是哪種類型训桶,這時候我們可以使用混合類型來表示累驮,但在使用該值之前酣倾,我們需要判斷該值到底是哪種類型,否則會引起錯誤:

// @flow
function stringify(value: mixed) {
  // $ExpectError
  return "" + value; // Error!
}

stringify("foo");
// @flow
function stringify(value: mixed) {
  if (typeof value === 'string') {
    return "" + value; // Works!
  } else {
    return "";
  }
}

stringify("foo");

任意類型 any

如果你想要一種方法來選擇不使用類型檢查器谤专,any 是做到這一點的方法躁锡。

使用any是完全不安全的,應(yīng)盡可能避免置侍。

例如映之,下面的代碼不會報告任何錯誤:

// @flow
function add(one: any, two: any): number {
  return one + two;
}

add(1, 2);     // Works.
add("1", "2"); // Works.
add({}, []);   // Works.

接口類型 interface

你可以使用 interface 以聲明您期望的類的結(jié)構(gòu)。

// @flow
interface Serializable {
  serialize(): string;
}

class Foo {
  serialize() { return '[Foo]'; }
}

class Bar {
  serialize() { return '[Bar]'; }
}

const foo: Serializable = new Foo(); // Works!
const bar: Serializable = new Bar(); // Works!

你也可以使用 implements 告訴Flow蜡坊,你希望類匹配一個接口杠输。這可以防止編輯類時發(fā)生不兼容的更改。

// @flow
interface Serializable {
  serialize(): string;
}

class Foo implements Serializable {
  serialize() { return '[Foo]'; } // Works!
}

class Bar implements Serializable {
  // $ExpectError
  serialize() { return 42; } // Error!
}

數(shù)組類型 Array

要創(chuàng)建一個數(shù)組類型秕衙,可以使用 Array<Type> 類型蠢甲,其中 Type 是數(shù)組中元素的類型。例如据忘,為你使用的數(shù)字?jǐn)?shù)組創(chuàng)建一個類型 Array<number>鹦牛。

let arr: Array<number> = [1, 2, 3];

暫時就介紹這么多,還有一些類型文章中沒有提到勇吊,更多更詳細(xì)的內(nèi)容請在Flow官網(wǎng)中查看曼追。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市汉规,隨后出現(xiàn)的幾起案子礼殊,更是在濱河造成了極大的恐慌,老刑警劉巖鲫忍,帶你破解...
    沈念sama閱讀 216,544評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件膏燕,死亡現(xiàn)場離奇詭異,居然都是意外死亡悟民,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,430評論 3 392
  • 文/潘曉璐 我一進(jìn)店門篷就,熙熙樓的掌柜王于貴愁眉苦臉地迎上來射亏,“玉大人,你說我怎么就攤上這事竭业≈侨螅” “怎么了?”我有些...
    開封第一講書人閱讀 162,764評論 0 353
  • 文/不壞的土叔 我叫張陵未辆,是天一觀的道長窟绷。 經(jīng)常有香客問我,道長咐柜,這世上最難降的妖魔是什么兼蜈? 我笑而不...
    開封第一講書人閱讀 58,193評論 1 292
  • 正文 為了忘掉前任攘残,我火速辦了婚禮,結(jié)果婚禮上为狸,老公的妹妹穿的比我還像新娘歼郭。我一直安慰自己,他們只是感情好辐棒,可當(dāng)我...
    茶點故事閱讀 67,216評論 6 388
  • 文/花漫 我一把揭開白布病曾。 她就那樣靜靜地躺著,像睡著了一般漾根。 火紅的嫁衣襯著肌膚如雪泰涂。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,182評論 1 299
  • 那天辐怕,我揣著相機與錄音负敏,去河邊找鬼。 笑死秘蛇,一個胖子當(dāng)著我的面吹牛其做,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播赁还,決...
    沈念sama閱讀 40,063評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼妖泄,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了艘策?” 一聲冷哼從身側(cè)響起蹈胡,我...
    開封第一講書人閱讀 38,917評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎朋蔫,沒想到半個月后罚渐,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,329評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡驯妄,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,543評論 2 332
  • 正文 我和宋清朗相戀三年荷并,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片青扔。...
    茶點故事閱讀 39,722評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡源织,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出微猖,到底是詐尸還是另有隱情谈息,我是刑警寧澤,帶...
    沈念sama閱讀 35,425評論 5 343
  • 正文 年R本政府宣布凛剥,位于F島的核電站侠仇,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏犁珠。R本人自食惡果不足惜逻炊,卻給世界環(huán)境...
    茶點故事閱讀 41,019評論 3 326
  • 文/蒙蒙 一互亮、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧嗅骄,春花似錦胳挎、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,671評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至屏积,卻和暖如春医窿,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背炊林。 一陣腳步聲響...
    開封第一講書人閱讀 32,825評論 1 269
  • 我被黑心中介騙來泰國打工姥卢, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人渣聚。 一個月前我還...
    沈念sama閱讀 47,729評論 2 368
  • 正文 我出身青樓独榴,卻偏偏與公主長得像,于是被迫代替她去往敵國和親奕枝。 傳聞我的和親對象是個殘疾皇子棺榔,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,614評論 2 353

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)隘道,斷路器症歇,智...
    卡卡羅2017閱讀 134,652評論 18 139
  • 第2章 基本語法 2.1 概述 基本句法和變量 語句 JavaScript程序的執(zhí)行單位為行(line),也就是一...
    悟名先生閱讀 4,148評論 0 13
  • Lua 5.1 參考手冊 by Roberto Ierusalimschy, Luiz Henrique de F...
    蘇黎九歌閱讀 13,788評論 0 38
  • Yo Yannan: I don't dare to say ,one of my friends in my g...
    鴻鑫在簡書閱讀 557評論 0 0
  • 概念 JNI(Java本地方法):使得java程序越過JVM直接調(diào)用本地方法提供了一種便捷的方式谭梗; CAS:1.是...
    jadefly閱讀 225評論 0 0