JS的静态类型检测,有内味儿了
我们知道 TypeScript 2.3 以后的版本支持使用--checkJs对.js文件进行类型检查和错误提示。 但是由于 JavaScript 是弱类型语言,在编写代码的时候,是无法检测变量的类型的。
因此每次运行代码类型报错的时候,我心中都会冒出来一个强烈的愿望:要是 JavaScript是强类型的多好!
好消息是,JSDoc 的 @ts-check,可以现实这个愿望。
立即上手
如果能有机会使用 TypeScript 那当然是最好,但是往往开发的老项目在早期都是 JavaScript 完成的,如果都迁移到 TypeScript 版本工作量是庞大的,而且不可避免出现许多bug问题,那么有没有一种方式可以无痛的在使用JavaScript的同时享受到TypeScript的类型检查呢?
答案就是 // @ts-check,在 js 文件的头部引入这样一行注释,然后配合JSDoc就可以在JavaScript代码中使用 TypeScript的类型检查了。
举个例子,在下图中我们首先声明了一个变量 a,然后把数字 1 赋给了它,接着又把字符串 '1' 赋给了它,看起来好像没有什么问题,而且运行起来也不会报错。
let a = 1;
a = 'a';
然后我们加上 // @ts-check 试试:
// @ts-check
/**
* @type {Number}
*/
let a = 1;
a = '1';
神奇的一幕出现了,在变量a赋值的下面,出现了红色波浪线,鼠标放上去提示:
let a: number
@type — {Number}
不能将类型“"1"”分配给类型“number”。ts(2322)

也就是说我们将一个字符串赋值给了一个数字类型的变量是有问题的,这个时候我们未运行程序,但是编辑器已经帮我们分析出了代码可能存在的问题,这时候我们运行代码,是没有报错的。
因为这个类型检测只是让我们按照TypeScript的强类型语言检测类型问题,但是我们依然是JavaScript代码依然会按照JavaScript的代码逻辑运行,如是TypeScript代码的话,这里运行就会报错。
JSDoc 类型标记
既然ts-check这么好用,我们来看看 JSDoc 类型的注释支持哪些类型的检测。
根据官方文档,JSDoc现在支持下面几个类型检测:
@type@param(or@argor@argument)@returns(or@return)@typedef@callback@template@class(or@constructor)@this@extends(or@augments)@enum
下面我们选择常用的标记进行说明,更多更详细的标记可以参考官方文档。
@type
描述:用来声明变量的类型。
/**
* - string类型
* @type {string}
*/
let a1;
/**
* - windows对象类型
* @type {Window}
*/
let a2;
/**
* - string或者boolean类型
* @type {string | boolean}
*/
let sb;
// -------- 多种方式指定数组类型--------
/** @type {number[]} */
var ns;
/** @type {Array.<number>} */
var nds;
/** @type {Array<number>} */
var nas;
// ---- 还可以指定对象字面量类型。 例如,一个带有a(字符串)和b(数字)属性的对象---
/** @type {{ a: string, b: number }} */
var var9;
@param和@returns
描述:@param语法和@type相同,但增加了一个参数名。
/**
* 声明函数参数类型
* @param {string} p1 - p1 是 string 类型参数
* @param {string=} p2 - p2 是可选的 string 类型参数
* @param {string} [p3] - 另外一种可选参数写法
* @param {string} [p4="test"] - p4 是可选的 string 类型参数(默认值为 "test")
* @return {string} - 函数返回值是 string 类型
*/
function fn3(p1, p2, p3, p4){
// TODO
}
/**
* 用 “return” 说明函数的返回值类型
* @return {number}
*/
function fn1() {}
/**
* 可以像使用 "@return" 一样使用 "@returns"
* @returns {{a: string, b: number}}
*/
function fn2() {}
@typedef
描述:@typedef 可以用来声明复杂类型,和@param类似的语法。
/**
* 用 "@typedef" 自定义复杂类型
* @typedef {Object} SpecialType - 创建一个新的类型 'SpecialType'
* @property {string} prop1 - SpecialType 属性 prop1 是 string 类型
* @property {number} prop2 - SpecialType 属性 prop2 是 number 类型
* @property {number=} prop3 - SpecialType 属性 prop3 是可选的 number 类型
* @prop {number} [prop4] - SpecialType 属性 prop4 是可选的 number 类型
* @prop {number} [prop5=42] - SpecialType 属性 prop5 是可选的 number 类型(默认值 42))
*/
/** @type {SpecialType} */
let specialTypeObject;
可以在第一行上使用
object或Object。
实验要求
经测试,在 VSCode 和 IDEA下可以直接使用ts-check 的类型检测,sublime等编辑器不可以,应该是要下载对应的插件才可以。
写在最后
对于老项目,使用 // @ts-check 和 JSDoc 来来享受TypeScript类型系统的好处是最简单、学习成本最低的方法。
而对于新项目,则更加推荐直接使用 TypeScript 来进行代码编写,并且各大框架里面都是用的TypeScript进行的代码编写,在可期的未来,TypeScript将会越来越受欢迎。
JS的静态类型检测,有内味儿了的更多相关文章
- 【JS】类型检测
本文首发于我的个人博客 : http://cherryblog.site/ 前言 js 中的类型检测也是很重要的一部分,所以说这篇文章我们就来讲一下怎么对 JavaScript 中的基本数据类型进行检 ...
- JS中 typeof,instanceof类型检测方式
在js中的类型检测目前我所知道的是三种方式,分别有它们的应用场景: 1.typeof:主要用于检测基本类型. typeof undefined;//=> undefined typeof 'a' ...
- JS中类型检测方式
在js中的类型检测目前我所知道的是三种方式,分别有它们的应用场景: 1.typeof:主要用于检测基本类型. typeof undefined;//=> undefined typeof 'a' ...
- JS做类型检测到底有几种方法?看完本文就知道了!
JS有很多数据类型,对于不同数据类型的识别和相互转换也是面试中的一个常考点,本文主要讲的就是类型转换和类型检测. 数据类型 JS中的数据类型主要分为两大类:原始类型(值类型)和引用类型.常见的数据类型 ...
- JS 类型检测
typeof 适合函数对象和基本类型的判断 typeof 100instanceof 适合判断对象类型 obj instanceof Object 基于原型链判断操作符,若做操作符不是对象,则会直接返 ...
- boost学习 内嵌类型检测 与 any 的代码练习
本文是学习 boost源码的一些练习 参考文章来自 刘未鹏 C++的罗浮宫(http://blog.csdn.net/pongba) 目录 http://blog.csdn.net/pongba/ar ...
- js安全类型检测
背景: 都知道js内置的类型检测,大多数情况下是不太可靠的,例如: typeof . instanceof typeof 返回一个未经计算的操作数的类型, 可以发现所有对象都是返回object ...
- JS数组类型检测
在强类型语言,数组类型检测是非常容易的事情(typeof就可以解决),而在弱语言JS数据类型就很容易混淆了. JS中常见的数据类型有:number.string.boolean.undefined.f ...
- flow 静态类型检查 js
1.flow介绍 https://ustbhuangyi.github.io/vue-analysis/prepare/flow.html#为什么用-flow 2.使用 (1)安装flow (2)项目 ...
随机推荐
- 入门Android底层需要的一些技能
<Android的设计与实现> Android框架层<Linux系统编程手册> Linux系统编程<Android内核剖析> 编译框架和romC语言和Linux内核 ...
- [springboot 开发单体web shop] 5. 用户登录及首页展示
用户登录及前端展示 用户登录 在之前的文章中我们实现了用户注册和验证功能,接下来我们继续实现它的登录,以及登录成功之后要在页面上显示的信息. 接下来,我们来编写代码. 实现service 在com.l ...
- 20190630模拟赛B(单调队列优化dp)
.dp无疑了其实. 在考场上,我写了一个错解,但是数据小都能过,只是会爆空间,考场上想着怎么用滚动数组优化来着....把错解的方程列出来吧 ;i<=n;i++) { ;j<=k;j++) ...
- 《吊打面试官》系列-Redis常见面试题(带答案)
你知道的越多,你不知道的越多 点赞再看,养成习惯 GitHub上已经开源,有面试点思维导图,欢迎[Star]和[完善] 前言 Redis在互联网技术存储方面使用如此广泛,几乎所有的后端技术面试官都要在 ...
- [转载]2.8 UiPath中断活动Break的介绍和使用
一.Break的介绍 Break: 用于结束当前循环. 注意: Break控件只能用于For Each 循环中 二.Break在UiPath中结合For Each循环的使用 1.打开设计器,在设计库中 ...
- nuxt.js 部署静态页面[dist]到gh-pages
一. 1.添加package.json { "name": "nuxtweb001", "version": "1.0.0&quo ...
- javascript关于box2djs和matterjs之间的选择
javascript关于box2djs和matterjs之间的选择box2djs资料少很多时候需要看c++版本资料 然后转化成js 还有转化成像素坐标不准确 matterjs文档丰富 上手容易 建议用 ...
- 深入理解计算机系统 第二章 信息的表示和处理 Part1 第二遍
<深入理解计算机系统> 第三版 第二遍读这本书,每周花两到三小时时间,能读多少读多少(这次看了 22 ~ 28 页) 第一遍对应笔记链接 https://www.cnblogs.com/s ...
- 有关html的标签以及css属性(border、div)
border 边框css属性 边框颜色 border-color边框样式 border-style:solid (实线)dashed(虚线)默认为none边框粗细 border-width:1px:默 ...
- pat 1008 Elevator(20 分)
1008 Elevator(20 分) The highest building in our city has only one elevator. A request list is made u ...