天天看点

编译期类型检查 in ClojureScript

 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&lt;Type&gt;</code>表示为数组类型且其元素类型可以继续递归下去,<code>Object&lt;Type&gt;</code>表示为对象类型且键类型为Type,<code>Object&lt;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>

继续阅读