如何为你的JS项目添加智能提示与类型检查详解


Posted in Javascript onMarch 12, 2019

前言

最近在做项目代码重构,其中有一个要求是为代码添加智能提示和类型检查。智能提示,英文为 IntelliSense,能为开发者提供代码智能补全、悬浮提示、跳转定义等功能,帮助其正确并且快速完成编码。说起来,JavaScript 作为一门动态弱类型解释型语言,变量声明后可以更改类型,并且类型在运行时才能确定,由此容易产生大量代码运行中才能发现的错误,相比 Java 等静态类型语言,开发体验上确实差了一截。更烦躁的是,智能提示就是依赖于静态类型检查的,所以在以前,指望 JavaScript 的智能提示完善度追上 Java 基本不可能。当然,时代在进步,TypeScript 已经问世许久,为 JavaScript 带来了静态类型检查以及其他诸多特性。JavaScript 的智能提示也已有了解决方案。调研了一段时间后,下文以 VSCode 编辑器作为开发工具,介绍一下如何为 JavaScript 加上智能提示以及类型检查。

基于 JSDoc

JSDoc 是目前最通用的 JavaScript API 文档生成器,根据其语法编写代码注释,可以十分方便地自动生成文档。由于 JSDoc 能提供详细的类型信息,其也被 VSCode 等编辑器接受应用于智能提示。例如,可以使用 @type 标签来赋予部分声明的 object 一个特殊类型:

/**
 * @type {{a: boolean, b: boolean, c: number}}
 */
var x = {a: true};
x.b = false;
x. // <- 由于 type 声明,"x" 将被提示含有属性 a,b 以及 c

JSDoc 最常见的使用是为函数的参数声明类型,使用 @param 来完成:

/**
 * @param {string} param1 - 这里可以用于解释参数含义
 */
function Foo(param1) {
 this.prop = param1; // param1 (以及 this.prop)均为 string 类型
}

为代码添加 JSDoc 注释使得阅读和理解代码更加方便(代码交接时再也不用抓狂了,当然前提是注释写得好),也保障了开发时的体验并且降低了很多运行时才能发现的数据类型方面的 bug。VSCode 基本支持 JSDoc 的常见语法,具体使用可参见JSDoc support in JavaScript。

基于 TypeScript 类型声明文件

除了使用 JSDoc 提前声明类型,更为激进的做法是直接使用微软开发的 TypeScript,为整个项目带来完善的静态类型检查。当然,对于老项目来说,改造的成本较为巨大(使用 Flow 也类似,要动的代码太多,况且 Flow 烂尾了)。不过由于和 TypeScript 师出同门,VSCode 能够直接读取前者的类型声明文件,来为 JavaScript 提供智能提示(实际上 JavaScript 的智能提示功能就是基于 TypeScript 团队为 VSCode 提供的 JavaScript 语言服务开发的)。 TypeScript 的类型声明文件以 .d.ts 为后缀,用于描述同名的 JavaScript 文件导出代码的类型,功能上类似于 C 语言的 .h 头文件。不严格地来说,ts 类型声明文件就像用 TypeScript 语法将 JSDoc 的注释重写了一遍并提取到了单独的文件中。VSCode 更是将二者作了融合,当你二者混用的时候,可以直接在 JSDoc 的注释中直接使用 ts 类型声明文件中定义的 interface 和 class 等。直接使用官方提供的示意图(图中是 Visual Studio,不过无伤大雅):

如何为你的JS项目添加智能提示与类型检查详解

对于自己的代码,可以编写对应的 ts 类型声明文件,而对于引用的第三方库,社区同样提供了解决方案:DefinitelyTyped 提供了常见的第三方库的类型声明文件。VSCode 有很多第三方库已经内置类型声明文件,自己下载的话直接使用 npm 即可:

# @types + 第三方库名称
npm i @types/express

关于 ts 类型声明文件的语法等相关信息,参见官网介绍。

另外,在 VSCode 中,类型检查并非默认开启,这意味着即使你有详尽的 JSDoc 注释或 ts 类型声明文件,依然可能在数据类型上栽跟头。开启方式为在项目根目录下添加 jsconfig.json 文件,并设置 "checkJs": true,示例如下:

{
 "compilerOptions": {
  "checkJs": true
 },
 
 // 位于此目录下的文件不进行静态检查和智能提示
 "exclude": [
  "node_modules",
  "**/node_modules/*"
 ]
}

总结

最后,无论是对老项目的改造或是新项目的开发,使用以上的方式添加智能提示和类型检查显而易见会略微拖慢开发速度,但我们认为,与智能提示带来的开发体验、将很多可能在运行时才能发现的错误通过类型检查前置解决、顺手完成的详细文档以及重构代码时的信心相比,这点速度的牺牲是值得的。

好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对三水点靠木的支持。

参考文档:

  • JavaScript in Visual Studio Code
  • Working with JavaScript
  • JavaScript Language Service in Visual Studio
Javascript 相关文章推荐
基于逻辑运算的简单权限系统(实现) JS 版
Mar 24 Javascript
Javascript中的var_dump函数实现代码
Sep 07 Javascript
JQuery调用绑定click事件的3种写法
Mar 28 Javascript
JavaScript实现获取某个元素相邻兄弟节点的prev与next方法
Jan 25 Javascript
Bootstrap Table表格一直加载(load)不了数据的快速解决方法
Sep 17 Javascript
详解JS获取HTML DOM元素的8种方法
Jun 17 Javascript
Vue实现点击后文字变色切换方法
Feb 11 Javascript
Vue使用高德地图搭建实时公交应用功能(地图 + 附近站点+线路详情 + 输入提示+换乘详情)
May 16 Javascript
vue登录页面cookie的使用及页面跳转代码
Jul 10 Javascript
JavaScript, select标签元素左右移动功能实现
May 14 Javascript
Vue父子组件传值的一些坑
Sep 16 Javascript
Vue中用JSON实现刷新界面不影响倒计时
Oct 26 Javascript
Vue项目引发的「过滤器」使用教程
Mar 12 #Javascript
通过JS运行机制的角度说说作用域
Mar 12 #Javascript
Jquery的autocomplete插件用法及参数讲解
Mar 12 #jQuery
如何使用pm2快速将项目部署到远程服务器
Mar 12 #Javascript
详解用Webpack与Babel配置ES6开发环境
Mar 12 #Javascript
详解微信小程序框架wepy踩坑记录(与vue对比)
Mar 12 #Javascript
javascript中数组的常用算法深入分析
Mar 12 #Javascript
You might like
PHP常用技巧总结(附函数代码)
2012/02/04 PHP
php笔记之:有规律大文件的读取与写入的分析
2013/04/26 PHP
php实现使用正则将文本中的网址转换成链接标签
2014/12/03 PHP
Jquery同辈元素选中/未选中效果的实例代码
2013/08/01 Javascript
EasyUI中datagrid在ie下reload失败解决方案
2015/03/09 Javascript
JavaScript中的函数嵌套使用
2015/06/04 Javascript
javascript中判断json的方法总结
2015/08/27 Javascript
JS实现对中文字符串进行utf-8的Base64编码的方法(使其与Java编码相同)
2016/06/21 Javascript
JS留言功能的简单实现案例(推荐)
2016/06/23 Javascript
jquery siblings获取同辈元素用法实例分析
2016/07/25 Javascript
nodejs的压缩文件模块archiver用法示例
2017/01/18 NodeJs
JQuery Ajax 异步操作之动态添加节点功能
2017/05/24 jQuery
js实现京东轮播图效果
2017/06/30 Javascript
bootstrap fileinput实现文件上传功能
2017/08/23 Javascript
微信小程序获取手机系统信息的方法【附源码下载】
2017/12/07 Javascript
Mac中安装nvm的教程分享
2017/12/11 Javascript
浅谈Angular 观察者模式理解
2018/11/01 Javascript
JS删除数组指定值常用方法详解
2020/06/04 Javascript
pymongo为mongodb数据库添加索引的方法
2015/05/11 Python
浅谈Django+Gunicorn+Nginx部署之路
2019/09/11 Python
Python Opencv提取图片中某种颜色组成的图形的方法
2019/09/19 Python
Windows下PyCharm2018.3.2 安装教程(图文详解)
2019/10/24 Python
Django通过dwebsocket实现websocket的例子
2019/11/15 Python
Python开发之身份证验证库id_validator验证身份证号合法性及根据身份证号返回住址年龄等信息
2020/03/20 Python
CSS3中border-radius属性设定圆角的使用技巧
2016/05/10 HTML / CSS
马来西亚和新加坡巴士票在线预订:CatchThatBus
2018/11/17 全球购物
Java提供了哪些企业应用编程接口
2015/02/13 面试题
如何理解委托
2012/01/06 面试题
几个MySql的面试题
2013/04/22 面试题
会展中心部门工作职责
2013/11/27 职场文书
人力资源部培训专员岗位职责
2014/01/02 职场文书
法人代表委托书
2014/04/04 职场文书
幼儿园小班家长评语
2014/12/30 职场文书
项目安全员岗位职责
2015/02/15 职场文书
2015年公司工作总结
2015/04/25 职场文书
老生常谈 使用 CSS 实现三角形的技巧(多种方法)
2021/04/13 HTML / CSS