摘要:擴(kuò)展靜態(tài)類型檢查語(yǔ)言與系列等語(yǔ)言有一點(diǎn)很大的不同,就是語(yǔ)言是弱類型語(yǔ)言。但其實(shí)很多開(kāi)發(fā)人員還是比較喜歡用來(lái)開(kāi)發(fā)項(xiàng)目,所以開(kāi)發(fā)出來(lái)幫助語(yǔ)言擴(kuò)展靜態(tài)類型檢查功能,規(guī)避上面提到的問(wèn)題。
js 擴(kuò)展:靜態(tài)類型檢查(facebook flow)
js 語(yǔ)言與 java、C 系列等語(yǔ)言有一點(diǎn)很大的不同,就是 js 語(yǔ)言是弱類型語(yǔ)言。js 語(yǔ)言的這個(gè)特性可能讓大家覺(jué)得 js 很自由,沒(méi)有強(qiáng)制性的約束,但是當(dāng)遇到大型項(xiàng)目的時(shí)候,js 的這個(gè)特性就會(huì)變得比較麻煩,因?yàn)檫@會(huì)導(dǎo)致團(tuán)隊(duì)的代碼很不可控。這個(gè)原因也是促使 TypeScript 誕生的一個(gè)很重要的原因。
但其實(shí)很多開(kāi)發(fā)人員還是比較喜歡用 js 來(lái)開(kāi)發(fā)項(xiàng)目,所以 facebook 開(kāi)發(fā)出 flow 來(lái)幫助 js 語(yǔ)言擴(kuò)展靜態(tài)類型檢查功能,規(guī)避上面提到的問(wèn)題。
1. 代碼示例flow 規(guī)定,在需要做 "flow 靜態(tài)類型檢查" 文件的開(kāi)頭加上 // @flow 這段注釋,讓工具識(shí)別這個(gè)文件需要做靜態(tài)類型檢查,否則就會(huì)當(dāng)作一般 js 文件對(duì)待,不做靜態(tài)類型檢查。
flow 靜態(tài)類型幾乎可以應(yīng)用到所有的 js 對(duì)象,包括 es6 擴(kuò)展的 class, module 等,也包括 jsx 語(yǔ)法。
以下是一些基礎(chǔ)的靜態(tài)類型舉例,更詳細(xì)的可以查看 Type Annotations | Flow.
1.1 基本類型與 js 的基本數(shù)據(jù)類型類似,包括:
boolean: 對(duì)應(yīng) js 的 Boolean 類型
number: 對(duì)應(yīng) js 的 Number 類型
string: 對(duì)應(yīng) js 的 String 類型
null: 對(duì)應(yīng) js 的 null
void: 對(duì)應(yīng) js 的 undefined
正常的 js 代碼
let hello = "hello"; // 聲明一個(gè)變量 hello = 2 * 2; // 重新賦值 hello = []; // 重新賦值
加上 flow 靜態(tài)類型檢查擴(kuò)展的代碼
// @flow let hello: string = "hello"; // 聲明一個(gè) string 類型的變量 hello = 2 * 2; // 報(bào)錯(cuò) hello = []; // 報(bào)錯(cuò) hello = "hi"; // 重新賦值1.2 函數(shù)
正常的 js 代碼
function plus(a, b) { return a + b; } plus(); // NaN plus(1); // NaN plus(1, 2); // 3 plus("hello"); // "helloundefined" plus("hello", " hi"); // "hello hi" plus({}, {}); // "[object Object][object Object]"
加上 flow 靜態(tài)類型檢查擴(kuò)展的代碼
// @flow // 定義一個(gè) "兩個(gè)數(shù)字參數(shù),返回值也是數(shù)字" 的函數(shù) function plus(a: number, b: number): number { return a + b; } plus(); // 報(bào)錯(cuò) plus(1); // 報(bào)錯(cuò) plus("hello"); // 報(bào)錯(cuò) plus("hello", " hi"); // 報(bào)錯(cuò) plus({}, {}); // 報(bào)錯(cuò) plus(1, 2); // 31.3 可能(Maybe),可選(Optional),語(yǔ)義(Literal),混合(Mixed)
可能(Maybe)類型用一個(gè) ? 在類型前面表示,包含類型本身、null、undefined
// @flow let hello: ?string; // 聲明一個(gè)數(shù)據(jù)類型可以是 string, null, undefined 的變量 hello = null; // 賦值 hello = undefined; // 重新賦值 hello = "hello"; // 重新賦值 hello = 1; // 報(bào)錯(cuò) hello = true; // 報(bào)錯(cuò)
可選(Optional)類型一般用于對(duì)象屬性或者函數(shù)參數(shù),在名稱后面加一個(gè) ?,包含類型本身、undefined
// @flow const obj: {hello? : string}; // 屬性 hello 可以是 string, undefined obj = {}; // 賦值 obj = {hello: undefined}; // 重新賦值 obj = {hello: "hello"}; // 重新賦值 obj = {hello: null}; // 報(bào)錯(cuò) obj = {hello: 1}; // 報(bào)錯(cuò) obj = {hello: true}; // 報(bào)錯(cuò) // 屬性 param 可以是 number, undefined function method(param?: number) { /* ... */ } method(); // 正常 method(undefined); // 正常 method(1.12); // 正常 method(null); // 報(bào)錯(cuò) method("hello"); // 報(bào)錯(cuò)
語(yǔ)義(Literal)類型一般用于聲明某個(gè),某幾個(gè)特定的值(多個(gè)值用 | 分隔)
// @flow let hello: "hello"; // 聲明一個(gè)只能賦值 "hello" 的變量 hello = "hello"; // 賦值 hello = "hi"; // 報(bào)錯(cuò) hello = 12; // 報(bào)錯(cuò) hello = undefined; // 報(bào)錯(cuò) hello = null; // 報(bào)錯(cuò) function method(param: 1 | "hi" | boolean): void { /* ... */ } method(); // 報(bào)錯(cuò),缺少參數(shù) method(1); // ok method(1.2); // 報(bào)錯(cuò),類型不對(duì) method("hi"); // ok method("hello"); // 報(bào)錯(cuò),類型不對(duì) method(true); // ok method(false); // ok
混合(Mixed)類型是指任意數(shù)據(jù)類型
// @flow let hello: mixed; // 聲明一個(gè) mixed 類型的變量 hello = "hello"; // 賦值 hello = "hi"; // 重新賦值 hello = 12; // 重新賦值 hello = undefined; // 重新賦值 hello = null; // 重新賦值1.4 復(fù)合類型
數(shù)組
// @flow let arr1: Array= [true, false, true]; // 聲明一個(gè)元素是 boolean 的數(shù)組 arr1 = [true, 1]; // 報(bào)錯(cuò),1 不是 boolean 值 arr1 = [""]; // 報(bào)錯(cuò),"" 不是 boolean 值 let arr2: Array = ["A", "B", "C"]; // 聲明一個(gè)元素是 string 的數(shù)組 let arr3: Array = [1, true, "three"] // 聲明一個(gè)元素是任意類型的數(shù)組 arr1 = [true, 1]; // 重新賦值 arr1 = [""]; // 重新賦值
map
// @flow // 聲明一個(gè) map 類型,其有一個(gè)名為 foo,類型 boolean 的子元素 let obj1: { foo: boolean } = { foo: true }; obj1 = {}; // 報(bào)錯(cuò),缺少 foo 這個(gè)屬性值 obj1 = {foo: 1}; // 報(bào)錯(cuò),屬性值 foo 的類型必須是 boolean obj1 = {foo: false, bar: "hello"}; // 重新賦值 // 聲明一個(gè) map 類型,其有名為 foo, bar, baz,類型 number, boolean, string 的子元素 let obj2: { foo: number, bar: boolean, baz: string, } = { foo: 1, bar: true, baz: "three", };
更靜態(tài)類型可以查看 Type Annotations | Flow.
2. 使用工具安裝
# 全局安裝 npm i -g flow-bin # 本地安裝 npm i -D flow-bin
使用
flow init # 初始化項(xiàng)目 flow check path/to/dir # 檢查這個(gè)目錄下所有的文件 flow check path/to/js/file # 檢查指定文件3. 配合 babel 一起使用
因?yàn)?flow 靜態(tài)類型只是對(duì) js 的擴(kuò)展,并不是 js 原生支持的,也不能直接運(yùn)行,所以,一般 flow 都是配合 babel 一起使用的,這樣就可以在程序運(yùn)行的時(shí)候進(jìn)行靜態(tài)類型檢查,達(dá)到我們想要的效果。
3.1 babel-preset-flow安裝 babel-preset-flow,這樣 babel 在轉(zhuǎn)碼 js 文件時(shí)就能識(shí)別 flow 的語(yǔ)法。
npm i -D babel-preset-flow
.babelrc
{ "presets": ["flow"] }
源文件(flow)
// @flow // 定義一個(gè) "兩個(gè)數(shù)字參數(shù),返回值也是數(shù)字" 的函數(shù) function plus(a: number, b: number): number { return a + b; } plus(); // 報(bào)錯(cuò) plus(1); // 報(bào)錯(cuò) plus("hello"); // 報(bào)錯(cuò) plus("hello", " hi"); // 報(bào)錯(cuò) plus({}, {}); // 報(bào)錯(cuò) plus(1, 2); // 3
轉(zhuǎn)碼后的文件
// 定義一個(gè) "兩個(gè)數(shù)字參數(shù),返回值也是數(shù)字" 的函數(shù) function plus(a, b) { return a + b; } plus(); // 報(bào)錯(cuò) plus(1); // 報(bào)錯(cuò) plus("hello"); // 報(bào)錯(cuò) plus("hello", " hi"); // 報(bào)錯(cuò) plus({}, {}); // 報(bào)錯(cuò) plus(1, 2); // 33.2 babel-plugin-flow-runtime
一般會(huì)在開(kāi)發(fā)環(huán)境下,使用 babel-plugin-flow-runtime 插件,這樣就可以在開(kāi)發(fā)的時(shí)候,實(shí)時(shí)檢查數(shù)據(jù)類型,就像原生的運(yùn)行 flow 靜態(tài)類型檢查一樣。(一般在產(chǎn)品環(huán)境不會(huì)使用這個(gè)功能,因?yàn)闀?huì)額外消耗 js 的性能)
npm i -D babel-plugin-flow-runtime flow-runtime
.babelrc
{ "presets": ["flow"], "plugins": ["flow-runtime"] }
源文件(flow)
// @flow // 定義一個(gè) "兩個(gè)數(shù)字參數(shù),返回值也是數(shù)字" 的函數(shù) function plus(a: number, b: number): number { return a + b; } plus(); // 報(bào)錯(cuò) plus(1); // 報(bào)錯(cuò) plus("hello"); // 報(bào)錯(cuò) plus("hello", " hi"); // 報(bào)錯(cuò) plus({}, {}); // 報(bào)錯(cuò) plus(1, 2); // 3
轉(zhuǎn)碼后的文件
import t from "flow-runtime"; // 定義一個(gè) "兩個(gè)數(shù)字參數(shù),返回值也是數(shù)字" 的函數(shù) function plus(a, b) { return a + b; } t.annotate(plus, t.function(t.param("a", t.number()), t.param("b", t.number()), t.return(t.number()))); plus(); // 報(bào)錯(cuò) plus(1); // 報(bào)錯(cuò) plus("hello"); // 報(bào)錯(cuò) plus("hello", " hi"); // 報(bào)錯(cuò) plus({}, {}); // 報(bào)錯(cuò) plus(1, 2); // 3
這個(gè)時(shí)候,js 文件就會(huì)導(dǎo)入 flow-runtime 模塊,對(duì) plus 函數(shù)的參數(shù) a, b 和返回值進(jìn)行數(shù)據(jù)類型檢查,如果不符合數(shù)據(jù)定義,就會(huì)報(bào)錯(cuò)。
4. 后續(xù)更多博客,查看 https://github.com/senntyou/blogs
作者:深予之 (@senntyou)
版權(quán)聲明:自由轉(zhuǎn)載-非商用-非衍生-保持署名(創(chuàng)意共享3.0許可證)
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/96960.html
摘要:原文鏈接翻譯于今天我們興奮的發(fā)布了的嘗鮮版,一個(gè)新的靜態(tài)類型檢查器。為添加了靜態(tài)類型檢查,以提高開(kāi)發(fā)效率和代碼質(zhì)量。這最終形成一個(gè)高度并行增量式的檢查架構(gòu),類似。知道縮小類型范圍時(shí)做動(dòng)態(tài)檢查的影響。 原文鏈接:https://code.facebook.com/posts/1505962329687926/flow-a-new-static-type-checker-for-java...
摘要:本文主要介紹了解決作為弱類型語(yǔ)言沒(méi)有類型檢查痛點(diǎn)的靜態(tài)類型檢查工具,并且介紹了在中使用的方法,最后介紹了一些常用的語(yǔ)法。 本文主要介紹了解決JS作為弱類型語(yǔ)言沒(méi)有類型檢查痛點(diǎn)的靜態(tài)類型檢查工具 Flow ,并且介紹了在WebStorm中使用Flow的方法,最后介紹了一些常用的Flow語(yǔ)法。 1. 簡(jiǎn)介 JS作為一種腳本語(yǔ)言是沒(méi)有類型檢測(cè)的,這個(gè)特點(diǎn)有時(shí)候用著很方便,但在一個(gè)較大的項(xiàng)目中...
摘要:系列引言最近準(zhǔn)備培訓(xùn)新人為了方便新人較快入手開(kāi)發(fā)并編寫高質(zhì)量的組件代碼我根據(jù)自己的實(shí)踐經(jīng)驗(yàn)對(duì)組件設(shè)計(jì)的相關(guān)實(shí)踐和規(guī)范整理了一些文檔將部分章節(jié)分享了出來(lái)由于經(jīng)驗(yàn)有限文章可能會(huì)有某些錯(cuò)誤希望大家指出互相交流由于篇幅太長(zhǎng)所以拆分為幾篇文章主要有以 系列引言 最近準(zhǔn)備培訓(xùn)新人, 為了方便新人較快入手 React 開(kāi)發(fā)并編寫高質(zhì)量的組件代碼, 我根據(jù)自己的實(shí)踐經(jīng)驗(yàn)對(duì)React 組件設(shè)計(jì)的相關(guān)實(shí)踐...
摘要:在年成為最大贏家,贏得了實(shí)現(xiàn)的風(fēng)暴之戰(zhàn)。和他的競(jìng)爭(zhēng)者位列第二沒(méi)有前端開(kāi)發(fā)者可以忽視和它的生態(tài)系統(tǒng)。他的殺手級(jí)特性是探測(cè)功能,通過(guò)檢查任何用戶的功能,以直觀的方式讓開(kāi)發(fā)人員檢查所有端點(diǎn)。 2016 JavaScript 后起之秀 本文轉(zhuǎn)載自:眾成翻譯譯者:zxhycxq鏈接:http://www.zcfy.cc/article/2410原文:https://risingstars2016...
摘要:資源官網(wǎng)安裝參考什么是是一個(gè)弱類型的解釋性語(yǔ)言,無(wú)法在編譯環(huán)節(jié)進(jìn)行靜態(tài)類型校驗(yàn),如果想也具備靜態(tài)類型檢查功能。那就得使用到由推出,官網(wǎng)是。 資源 官網(wǎng):https://flow.org/ 安裝:https://flow.org/en/docs/inst... 參考:https://www.01hai.com/note/av... https://www.jianshu.com/p...
閱讀 2000·2021-11-22 19:20
閱讀 2648·2021-11-22 13:54
閱讀 1980·2021-09-04 16:40
閱讀 1830·2021-08-13 11:54
閱讀 2681·2019-08-30 15:55
閱讀 3472·2019-08-29 13:51
閱讀 535·2019-08-29 11:09
閱讀 3014·2019-08-26 14:06