標籤:

跟上前端的步伐[1] - Flow: JS Static Type Checker

我們在寫動態語言(Python,Javascript)的時候,會感覺非常的爽,因為不用擔心什麼類型定義,直接刷刷刷寫一堆,碼率飛快,非常有成就感。然而,當項目規模一大之後,慢慢體現出來的一個巨大的缺點就是,維護和重構起來非常艱難。

當然,你可以通過寫很多測試用例來保證質量。但是,假如我們能像靜態語言一樣,在寫代碼的時候讓「編譯器」幫我們檢查出大部分的語法/類型錯誤,但是又不影響代碼運行(不需要運行時動態檢查類型),開發效率將會大大提高。

Facebook開源的Flow (A static type checker for JavaScript) 做的就是這件事情:它允許你在寫JS代碼的時候,在代碼裡面加上變數的類型註解,然後在發布代碼的時候把註解刪掉,轉換成正常的JS代碼。舉個例子,就像下面這樣:

function len(x: Array<mixed>): number {n return x.length;n}n

然後如果你不小心寫了如下的代碼

function len(x: Array<mixed>): string {n return x.length;n}n

那麼你只要在項目里運行Flow提供的檢查工具,它就會拋出錯誤

number This type is incompatible with the expected return type string.n

上面這個只是非常簡單的例子。更加酷炫的例子如下:

可以寫類似於C語言一樣的typedef

type ObjectWithManyProperties = { n foo: string,n bar: number,n baz: boolean,n qux: (foo: string, bar: number) => boolean;n}n

支持Enum

type StarbuckCupSizeEnum = regular | large | extraLarge;n

可以按照正常語言的方法做面向對象編程,不需要寫反人類的JS類。這意味著你也可以像Java一樣定義介面和類繼承(你看Javascript到最後還是繞回Java了嘛)

支持范型

作類似於folly::Future的類型推導(這個真是驚艷到了)

function future(): Promise<number> {n return new Promise(function(resolve, reject) {n resolve(hello); // This wont work because its string, not number.n });n}n

在具體應用中一般會整合到Babel裡面(Babel就是一個允許你用非常前衛,還沒有被瀏覽器支持的JS語法寫JS代碼,然後自動轉化成語法為瀏覽器支持的JS代碼的工具),再加上Grunt或者其他Task Runner,在每次保存源文件的時候,自動觸發代碼轉換程序。

實話說我第一次接觸到這個語法的時候,真是覺得絕了——它幾乎把JS變成了一個可以跟世界上最好的語言媲美的語言,從此再也不需要見到Plain Javascript那樣醜陋的代碼了。說幾乎是因為它畢竟有一定的局限性,有些Corner case沒辦法照顧得很好,但是大部分的情況下,我感覺它可以把JS開發效率起碼提高好幾倍。

[1] A static type checker for JavaScript


推薦閱讀:

TAG:前端开发 |