使用duckie爲JS作強類型檢查

JS是一門動態類型語言,在定義一個函數時,沒法爲其進行強類型指定,如:javascript

function hello(name: string, content: string) {
   // 若是name或content不是string類型的話,就拋異常
}

若是沒有類型指定的話:java

  1. 開發者經常不知道一個函數須要什麼數據類型。
  2. 出現奇怪錯誤時,給debug形成麻煩。

其實業界已經有兩種解決辦法:node

  1. 使用JSDoc對函數進行註釋
  2. 使用強類型語言編程,最後編譯成JS.

首先說第一種,JSDoc的語法規則可謂麻煩,註釋簡單類型時還稍微OK,如:webpack

/**
 * @param string name the name of the person
 * @param string content the content to say
 */
function hello(name, content) { //... }

但若是我想對以下的數據結構作註釋呢?ios

javascript{
    name: "jack",
    age: 18,
    address: {
        country: 'china',
        city: 'beijing'
    },
    keywords: ['student', 'programmer', 'ios']
}

基本上沒幾我的能寫的對JSDoc的註釋,要對上述結構進行JSDoc,你須要:git

  1. 艱難的Google它奇怪的語法。
  2. 寫出來還很醜。
  3. 最後其它開發者也看不懂。
  4. 參數傳錯也沒有錯誤提示。(WebStorm必定程度上能夠進行類型推導)。

第二種,嗯,就不說了。github

要想基本沒有學習成本的進行類型聲明和檢查,下面進入正題,使用duckie.web

安裝

對於node/browserify/webpack的用戶,直接:npm

npm install duckie

var t = require('duckie'); // go!

對於瀏覽器用戶,能夠直接使用https://github.com/ssnau/duckie/tree/master/build下已經編譯好的文件,也可用bower安裝。最後可使用window.duckie編程

入門

回到篇首,若是想實現function hello(name:string, content:string)該如何實現呢?

function hello(name, content) {
    duckie.string.assert(name);
    duckie.string.assert(content);

    // 若是上面的斷言不成立的話,將拋出異常
}

string只是個示例,duckie總共支持以下一些基本類型:

  • boolean/bool
  • number
  • string
  • undefined
  • null
  • array
  • object
  • anything, 表示任意類型

即以下斷言都爲真:

duckie.boolean.assert(true);
duckie.number.assert(123);
duckie.string.assert('hello');
duckie.undefined.assert(undefined);
duckie.null.assert(null);
duckie.aray.assert([1,2,3]);
duckie.object.assert({name: 'jack'});
duckie.anything.assert('blabla');

若是隻是斷言簡單的類型,那大可沒必要用duckie,JSDoc就基本能完成這種功效,除了不會拋異常。

duckie真正有效的地方在於,定義複雜的數據結構。

咱們一個一個提及。

若是一個變量是枚舉類型,如何限定它的枚舉值呢?

使用oneOf.

// 只有值爲male或female的變量,才能經過認證
duckie.oneOf(['male', 'female']).assert('male') => true
duckie.oneOf(['male', 'female']).assert(1)      => false

若是一個變量的類型,多是undefined,多是string,該如何表示?

使用maybe

duckie.maybe(String).assert('hello') => true
duckie.maybe(String).assert(undefined) => true
duckie.maybe(String).assert(123) => false

/*注:String可替換爲duckie.string或"string",意義都同樣*/

若是一個變量的類型多是string,多是number呢?

使用oneOfType

duckie.oneOfType([String, Number]).assert(1) => true
duckie.oneOfType([String, Number]).assert("hello") => true
duckie.oneOfType([String, Number]).assert(true) => false

若是一個變量是一個由數字組成的數組,該如何表示?

使用arrayOf(Number),或[Number].

// 使用arrayOf
duckie.arrayOf(Number).assert([1,2,3]) => true
// 直接使用[/*類型*/]
duckie([Number]).assert([1,2,3]) => true
duckie(['number']).assert(['hello', 'world']) => false

/* 注: 類型聲明使用Number,duckie.number 和 'number' 效果是同樣的。*/

若是一個變量是由一些key:value組成呢?

使用objectOf,或[].

//例如定義一個Person數據結構,典型的變量以下:
var person = {
    name: 'jack',
    age: 18
};

duckie.objectOf({
    name: String,
    age: Number
}).assert(person)  => true

duckie({
    name: String,
    age: Number
}).assert(person) => true

// 鴨子斷言,即只要求被斷言對象符合定義的
// 鍵值類型要求,而不要求精確匹配鍵數量
duckie({
    name: String
}).assert(person) => true

duckie({
    name: Number
}).assert(person) => false

若是一個變量是個object,裏面有些值是數組呢?

以聲明變量的方式用duckie聲明你的類型。

// 好比篇首這東西
var person = {
    name: "jack",
    age: 18,
    address: {
        country: 'china',
        city: 'beijing'
    },
    keywords: ['student', 'programmer', 'ios']
}

// 使用duckie聲明
duckie({
    name: String,
    age: Number,
    address: {
        country: String,
        city: String
    },
    keywords: [String]
}).assert(person)  => true

聲明一個類型跟聲明一個對象般簡單,徹底沒有學習成本。

總結

使用duckie能夠像聲明一個變量那樣聲明你的類型,且能夠在運行時進行類型檢查。若有什麼建議,歡迎提議。

相關文章
相關標籤/搜索