ClojureScript與JavaScript一樣采取動态類型,但由于需要通過Google Closure Compiler編譯後才能運作,是以我們可以如同JS那樣借助GCC的注解來引入編譯時類型檢查,達到同樣靜态類型的效果。
GCC的編譯時類型檢查僅當<code>optimizations</code>為<code>simple</code>或<code>advanced</code>時有效。我們以<code>:cljsbuild</code>下的dev配置為例
請注意,<code>:check-types</code>必須設定為<code>:warning</code>,若設定為<code>:error</code>時,就會報<code>Math.imul引發的JSC_DUP_VAR_DECLARATION_TYPE_MISMATCH異常</code>,導緻項目其他代碼均不能被編譯。希望大神指點迷津~~
首先GCC用到的注解文法僅為JSDoc的子集,是以直接看GCC的注解即可,而ClojureScript一般就用如下幾個
接下來就是重點了,我們寫了這麼多還不就是想引入資料的類型描述嗎?那關鍵就是上述代碼中Type到底應該怎麼寫了!
1.标量類型<code>number</code>,<code>string</code>,<code>boolean</code>,<code>null</code>,<code>undefined</code>
注意
一、标量類型預設表示變量或參數的實際值為不可為null(non-nullable)。若要辨別為可為null(nullable),那麼隻需前置一個問号<code>?</code>即可(<code>?number</code>,<code>?string</code>)
2.對象類型<code>Object</code>,<code>Function</code>,<code>Number</code>,<code>String</code>,<code>Boolean</code>,<code>Date</code>和其他Cljs或自定義的對象類型。
一、對于非全限定的對象類型,會自動展開為目前命名空間的類型(如目前命名空間為<code>my-proj.core</code>,那麼<code>MyArray</code>會展開為<code>my-proj.core/MyArray</code>)
二、對象類型預設表示變量或參數的實際值可為null(nullable)。若要辨別為不可為null(non-nullable),那麼隻需前置一個感歎号<code>!</code>即可(如<code>!Object</code>,<code>!Date</code>等)
3.組合類型,如<code>(number|string)</code>,即是實際值可為數字也可為字元串。
4.集合/字典,<code>Array<Type></code>表示為數組類型且其元素類型可以繼續遞歸下去,<code>Object<Type></code>表示為對象類型且鍵類型為Type,<code>Object<Type1,Type2</code>表示為對象類型且鍵類型為Type1而值類型為Type2
5.函數類型
<code>function(Type1,Type2)</code>,表示函數含資料類型為Type1和Type2兩個形參。
<code>function(Type1,Type2):Type3</code>,表示函數含資料類型為Type1和Type2兩個形參,且傳回值類型為Type3。
<code>function(...Type)</code>,表示函數含資料類型為Type的可變形參,注意可變形參必須作為最後一個形參出現。
<code>function(Type=)</code>,表示函數含可選的資料類型為Type的形參,注意可選形參後不能聲明必填的形參。
注意注意!
形參和逗号間千萬不要留白格,否則編譯時會報警告的哦!
Type為function()時不能在聲明傳回值類型,否則編譯時輝報警告!
6.什麼類型都可以,<code>*</code>
1.封裝chrome.runtime.onMessage玩玩
注意:<code>window.MessageSend</code>既不是GCC内置的類型也不是我們自定義類型,而是外部定義的資料類型,是以我們需要添加externs檔案讓GCC識别。
是以得到的配置如下
如官網所講,這部分的内容仍在發展階段,是以還有很多不完善的地方。不過也不影響我們現在就開始使用,是以良好的代碼注釋從來都需要的!
<a href="https://clojurescript.org/reference/compile-time-type-checking">https://clojurescript.org/reference/compile-time-type-checking</a>
<a href="https://github.com/google/closure-compiler/wiki/Annotating-JavaScript-for-the-Closure-Compiler">https://github.com/google/closure-compiler/wiki/Annotating-JavaScript-for-the-Closure-Compiler</a>
<a href="https://github.com/google/closure-compiler/wiki/Types-in-the-Closure-Type-System">https://github.com/google/closure-compiler/wiki/Types-in-the-Closure-Type-System</a>
<a href="https://github.com/google/closure-compiler/wiki/Warnings">https://github.com/google/closure-compiler/wiki/Warnings</a>