作为弱类型的
JavaScript
写起来爽,维护起来更爽。—— 鲁迅·沃梅硕果
近几年,前端技术的发展可以用 Big Boom
来形容,因此 JavaScript
也被大规模的运用在项目中,由此也产生了代码的维护问题,所谓 动态类型一时爽,代码重构火葬场
。
其实不仅仅是代码重构,在日常开发中也能感受到弱类型语言的不足。举个例子,现在有个函数 renderUserList
, 作用是将用户列表显示在界面上
function renderUserList(el, userList) { |
我敢打赌,大家在写这种类型函数的时候,都是在盲写,因为我们不知道传入的 el
和 userList
到底是什么类型。更不知道 el
下面有哪些方法,写的时候都如此费劲,跟别谈维护了。其实我们可以通过一些简单的操作,让这个函数写起来更轻松,就像下面一样:
那么,到底是怎么实现的呢?接下来就要介绍本文的主角 JSDoc 和 VSCode
JSDoc是一个根据javascript文件中注释信息,生成JavaScript应用程序或库、模块的API文档 的工具。你可以使用他记录如:命名空间,类,方法,方法参数等。
在 VSCode
中会自动根据 JSDoc
的标注对变量、方法、方法参数等进行类型推断,通过 TypeScript
来进行智能提示,因此从编写注释开始学习 TypeScript
也是一个不错的选择。
变量
用 @type
标注变量的类型
基础类型
/** |
联合类型
如果一个变量可能是多种类型,则可以使用联合类型
/** |
自定义类型
我们经常用到自定义类型,也就是 JavaScript
中的对象,对于简单的对象,可以用下面的写法
/** |
对于键值对比较多的复杂对象,可以使用 @typedef
来定义复杂类型,用 prop
或者 property
来定义对象的属性。
/** |
数组
可以使用 []
或者 Array
表示数组
/** |
对于已经定义的类型或者已经声明的变量,也是可以直接使用,下面分别声明一个 user
数组和 goods
数组
/** |
如果不确定数组的每一项具体类型,可以使用 any
*
或者交叉类型
/** |
泛型
/** |
函数
用 @name
表示函数的名称
用 @param
表示函数的参数
用 @return
或 @returns
表示函数的返回值
一般函数的写法大致分为两种:声明式函数和函数表达式。
函数表达式
/** |
声明式函数
/** |
通过上面的注释写法,便可以在函数 fn
内部正确的识别出两个参数的类型,并且该函数返回值类型为数组。
对于函数参数的类型,写法和上面的变量写法一致,区别是将 @type
换成了 @param
,函数的返回值也是同样的道理。
对象的方法
对函数的注释同样适用于对象的方法
var o = { |
内置类型和其它类型
上面的例子只是简单的用到了一些常见的类型,然而在实际开发中,我们用到的不止这些,比如开始文章开头的例子中,有用到了 DOM
对象,那该怎么编写注释呢?其实 VSCode
已经为我们提供了很多的类型了,比如 DOM
对象对应的类型是 HTMLElement
, 事件对象对应的类型是 Event
,同时 DOM
对象还可以更细化,比如 HTMLCanvasElement
、HTMLImageElement
等等。
同时,我们在开发中也会用到第三方的类库或框架,通常情况下,这些类库都会有一份以 d.ts
结尾的声明文件,该声明文件中包含了所用到类型的所有提示,以最为经典的 jQuery
为例,如果在时在 webpack
环境下,在通过 npm 安装 jQuery 后,需要再单独安装对应的声明文件 @types/jquery
,这样 VSCode 就可以正确的识别 $
符号,也可以在 JSDoc 中使用 JQuery
, JQueryStatic
等这都类型了,就像下面这样
/** |
大部分情况下,通过 npm 发布的包,都会包含其对应的声明文件,如果没有的话,可以通过这个地址 TypeSearch 来搜索一下并安装 ,如果感兴趣可以到这个仓库 DefinitelyTyped 看看。当然你也可以提供一些仓库内目前还没有声明文件,别人会非常感谢你的!
当然并不是所有的项目都用到了 npm ,仍有很多项目在使用 script
这种方式从 cdn 来引入 .js
文件,这种情况下用不到 webpack ,也用不到 npm ,那这个时候就要从上面所提到的仓库地址 DefinitelyTyped 来下载对应的声明文件了,然后通过 /// <reference path="" />
这种形式来引入声明文件,就像下面这样
/// <reference path="./node_modules/@types/jquery/index.d.ts"/> |
个人建议:即使是通过 cdn 方式来引入 .js
文件,也可以通过 npm 来安装 @types/
,这样和在每个文件中通过 /// <reference path="" />
引入声明文件相比,还是方便很多的。
总结
以上便是关于利用 JSDoc 实现 JavaScript 的类型提示。当然还有一些更深入的用法,比如全局模板文件,命名空间等,但是这些和 TypeScript 关系更大一些。当有一天你发现 JSDoc 已经不能满足你的时候,便是向着 TypeScript 大举进攻的时候了。