摘要:本文主要介紹了解決作為弱類型語言沒有類型檢查痛點的靜態類型檢查工具,并且介紹了在中使用的方法,最后介紹了一些常用的語法。
本文主要介紹了解決JS作為弱類型語言沒有類型檢查痛點的靜態類型檢查工具 Flow ,并且介紹了在WebStorm中使用Flow的方法,最后介紹了一些常用的Flow語法。
1. 簡介JS作為一種腳本語言是沒有類型檢測的,這個特點有時候用著很方便,但在一個較大的項目中就會發現這其實是一件挺糟糕的特性,因為和你協作的程序員往往不太清楚你所寫的代碼到底哪種類型才是正確的,等到代碼重構就比較麻煩。于是基于這個需求有了Typescript和Flow的產生,今天這里主要介紹Flow。
Flow是一個由Facebook出品的JavaScript靜態類型檢查工具,它與Typescript不同的是,它可以部分引入,不需要完全重構整個項目,所以對于一個已有一定規模的項目來說,遷移成本更小,也更加可行。除此之外,Flow可以提供實時增量的反饋,通過運行Flow server不需要在每次更改項目的時候完全從頭運行類型檢查,提高運行效率。Flow和Typescript都是給Javascript增加類型檢查的優秀解決方案,兩者的簡單對比如下:
工具 | Flow | TypeScript |
---|---|---|
公司 | 微軟 | |
star | 16k | 33k |
文檔支持程度 | 中等 | 多 |
優點 | 自由度高,老項目遷移成本低 | 工程化強,社區活躍,官方支持力度高 |
對于兩者使用場景差別,可以簡單總結為:對于新項目,可以考慮使用TypeScript或者Flow,對于已有一定規模的項目則建議使用Flow進行較小成本的逐步遷移來引入類型檢查。Flow可以幫助找出由于不合理的類型操作引起的錯誤,包括運算符操作,函數參數類型和返回值類型等。Flow也支持自定義類型聲明,泛型聲明等類型語言相關的操作,詳細的內容可以參考文檔。
引入方法:在需要使用 Flow 進行類型檢查的 js 文件開頭加入 // @flow 或者 /* @flow */,即可引入Flow,一個簡單例子:
// @flow function square(n: number): number { return n * n; } square("2"); // Error!2. 安裝方法
npm安裝:
npm install --save-dev babel-cli babel-preset-flow flow-babel-webpack-plugin babel-preset-es2015 babel-preset-env babel-plugin-transform-class-properties
我是全局安裝的:
npm install -g babel-cli babel-preset-flow flow-bin flow-babel-webpack-plugin babel-preset-es2015 babel-preset-env babel-plugin-transform-class-properties
在.babelrc文件加入:
{ "presets": ["flow", "es2015"], "plugins": [ "transform-vue-jsx", "transform-runtime", "transform-class-properties" ] }
設置一下WebStorm:通過 File>Settings>Languages&Frameworks>JavaScript 選擇Flow,Flow package可以選擇你項目下的flow-bin,當然你也可以全局安裝flow-bin,然后在這里設置后就可以在每個項目中都使用Flow了 。
但是flow不能直接在node或瀏覽器環境中使用,所以我們必須用babel編譯后才能使用,使用File watcher:
在項目目錄下運行flow init,會自動生成一個文件.flowconfig,這個文件可以配置flow,我的配置:
[ignore] .*/node_modules/.*/build/.* /config/.* [options] module.file_ext=.js module.file_ext=.vue
現在當我們在項目中使用Flow時WebStorm可以給出智能的提示了。
并且多了一個窗口 Flow 給出文檔中所有提示:
3. 使用最新的 ECMAScript 標準定義了 7 種數據類型: 6種原始類型:Boolean、Null、Undefined、Number、String、Symbol 和 Object
在Flow中也是使用這幾種類型作為標注:
使用原始類型:
// @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的構造函數,是對象類型的。
Boolean在Flow中,默認并不會轉換類型,如果你需要轉換類型請使用顯示或隱式轉換,例如:
// @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兼有 null 和 undefined。Flow將這些視為多帶帶的類型:null 和 void(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)來創建它們。
除了問號 ? 后跟著的類型,也許類型也可以是 null 或者 void 類型。
// @flow function acceptsMaybeString(value: ?string) { // ... } acceptsMaybeString("bar"); // Works! acceptsMaybeString(undefined); // Works! acceptsMaybeString(null); // Works! acceptsMaybeString(); // Works!可選的對象屬性
對象類型可以具有可選屬性,問號 ? 位于屬性名稱后面。
{ propertyName?: string }
除了它們的設定值類型之外,這些可選屬性也可以被 void 完全省略。但是,他們不能 null。
// @flow function acceptsObject(value: { foo?: string }) { // ... } acceptsObject({ foo: "bar" }); // Works! acceptsObject({ foo: undefined }); // Works! acceptsObject({ foo: null }); // Error! acceptsObject({}); // Works!可選的函數參數
函數可以具有可選參數,其中問號 ? 出現在參數名稱后面。同樣,該參數不能為 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!
您可以使用這些類型的原始值:
布爾值: true 或 false
數字:像 42 或 3.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是完全不安全的,應盡可能避免。
例如,下面的代碼不會報告任何錯誤:
// @flow function add(one: any, two: any): number { return one + two; } add(1, 2); // Works. add("1", "2"); // Works. add({}, []); // Works.接口類型 interface
你可以使用 interface 以聲明您期望的類的結構。
// @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,你希望類匹配一個接口。這可以防止編輯類時發生不兼容的更改。
// @flow interface Serializable { serialize(): string; } class Foo implements Serializable { serialize() { return "[Foo]"; } // Works! } class Bar implements Serializable { // $ExpectError serialize() { return 42; } // Error! }數組類型 Array
要創建一個數組類型,可以使用 Array
let arr: Array= [1, 2, 3];
暫時就介紹這么多,還有一些類型文章中沒有提到,更多更詳細的內容請在Flow官網中查看。
4. 移除Flow內容因為Flow的語法并不是標準的JavaScript語法,所以我們要在代碼最終上線前移除Flow相關的代碼(主要是那些固定類型的描述,如果只是添加了@flow,直接應用即可)
flow-remove-types這個程序會將你所有標有@flow的內容進行移除。。然后將移除后的代碼生成后指定的目錄下
npm i -g flow-remove-types flow-remove-types src/ --out-dir dist/ # src 源文件地址 # dist 生成后的地址babel+webpack
安裝一個webpack插件
npm i -D flow-babel-webpack-plugin
然后我們修改 .babelrc 文件,添加如下配置:
{ "plugins": [ "transform-flow-comments" ] }
然后在webpack.config.js或 webpack.dev.config.js、 webpack.prod.config.js、文件中添加:
const FlowBabelWebpackPlugin= require("flow-babel-webpack-plugin") module.exports = { plugins: [ new FlowBabelWebpackPlugin() ] }
在babel編譯JavaScript的同時也就會將Flow內容進行移除了。
網上的帖子大多深淺不一,甚至有些前后矛盾,在下的文章都是學習過程中的總結,如果發現錯誤,歡迎留言指出~
參考:
使用Flow來檢測你的JS
vue2.0項目配置flow類型檢查
用flow.js提升前端開發的體驗
Flow靜態類型檢查及在Vue項目中的使用
如何在項目中使用 flow js
PS:歡迎大家關注我的公眾號【前端下午茶】,一起加油吧~
另外可以加入「前端下午茶交流群」微信群,長按識別下面二維碼即可加我好友,備注加群,我拉你入群~
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/94209.html
摘要:介紹是個的靜態類型檢查工具,由出品的開源碼項目,問世只有一年多,是個相當年輕的項目。現在,提供了另一個新的選項,它是一種強靜態類型的輔助檢查工具。 showImg(https://segmentfault.com/img/bVH6mL?w=1200&h=675); 本章的目標是提供一些Flow工具的介紹與使用建議。Flow本質上也只是個檢查工具,它并不會自動修正代碼中的錯誤,也不會強制...
摘要:擴展靜態類型檢查語言與系列等語言有一點很大的不同,就是語言是弱類型語言。但其實很多開發人員還是比較喜歡用來開發項目,所以開發出來幫助語言擴展靜態類型檢查功能,規避上面提到的問題。 js 擴展:靜態類型檢查(facebook flow) js 語言與 java、C 系列等語言有一點很大的不同,就是 js 語言是弱類型語言。js 語言的這個特性可能讓大家覺得 js 很自由,沒有強制性的約束...
摘要:一是一種弱類型動態類型檢查的語言。動態類型與靜態類型的核心區別動態類型的類型檢查是是在代碼運行的時候進行的,靜態類型的類型檢查則是在編譯時進行。 一、js是一種弱類型、動態類型檢查的語言。 弱類型:在定義變量時,可以為變量定義復制任何數據,變量的數據類型不是固定死的,這樣的類型叫做弱類型。 var a = 10; a = abc; a = []; a = function() {}...
摘要:原文鏈接翻譯于今天我們興奮的發布了的嘗鮮版,一個新的靜態類型檢查器。為添加了靜態類型檢查,以提高開發效率和代碼質量。這最終形成一個高度并行增量式的檢查架構,類似。知道縮小類型范圍時做動態檢查的影響。 原文鏈接:https://code.facebook.com/posts/1505962329687926/flow-a-new-static-type-checker-for-java...
閱讀 2529·2021-07-26 23:38
閱讀 3430·2019-08-30 13:10
閱讀 2316·2019-08-29 18:33
閱讀 2321·2019-08-29 16:12
閱讀 987·2019-08-29 10:59
閱讀 1798·2019-08-26 17:40
閱讀 766·2019-08-26 11:59
閱讀 812·2019-08-26 11:41