热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

使用duckie为JS做强类型检查

JS是一门动态类型语言,在定义一个函数时,无法为其进行强类型指定,如:functionhello(name:string,c

JS是一门动态类型语言,在定义一个函数时,无法为其进行强类型指定,如:

function hello(name: string, content: string) {// 如果name或content不是string类型的话,就抛异常
}

如果没有类型指定的话:

  1. 开发者常常不知道一个函数需要什么数据类型。
  2. 出现奇怪错误时,给debug造成麻烦。

其实业界已经有两种解决办法:

  1. 使用JSDoc对函数进行注释
  2. 使用强类型语言编程,最后编译成JS.

首先说第一种,JSDoc的语法规则可谓麻烦,注释简单类型时还稍微OK,如:

/*** @param string name the name of the person* @param string content the content to say*/
function hello(name, content) { //... }

但如果我想对如下的数据结构做注释呢?

Javascript{name: "jack",age: 18,address: {country: 'china',city: 'beijing'},keywords: ['student', 'programmer', 'ios']
}

基本上没几个人能写的对JSDoc的注释,要对上述结构进行JSDoc,你需要:

  1. 艰难的Google它奇怪的语法。
  2. 写出来还很丑。
  3. 最后其它开发者也看不懂。
  4. 参数传错也没有错误提示。(WebStorm一定程度上可以进行类型推导)。

第二种,嗯,就不说了。

要想基本没有学习成本的进行类型声明和检查,下面进入正题,使用duckie.

安装

对于node/browserify/webpack的用户,直接:

npm install duckievar t = require('duckie'); // go!

对于浏览器用户,可以直接使用https://github.com/ssnau/duckie/tree/master/build下已经编译好的文件,也可用bower安装。最后可以使用window.duckie

入门

回到篇首,如果想实现function hello(name:string, content:string)该如何实现呢?

function hello(name, content) {duckie.string.assert(name);duckie.string.assert(content);// 如果上面的断言不成立的话,将抛出异常
}

string只是个示例,duckie总共支持如下一些基本类型:

  • boolean/bool
  • number
  • string
  • undefined
  • null
  • array
  • object
  • anything, 表示任意类型

即如下断言都为真:

duckie.boolean.assert(true);
duckie.number.assert(123);
duckie.string.assert('hello');
duckie.undefined.assert(undefined);
duckie.null.assert(null);
duckie.aray.assert([1,2,3]);
duckie.object.assert({name: 'jack'});
duckie.anything.assert('blabla');

如果只是断言简单的类型,那大可不必用duckie,JSDoc就基本能完成这种功效,除了不会抛异常。

duckie真正有效的地方在于,定义复杂的数据结构。

我们一个一个说起。

如果一个变量是枚举类型,如何限定它的枚举值呢?

使用oneOf.

// 只有值为male或female的变量,才能通过认证
duckie.oneOf(['male', 'female']).assert('male') => true
duckie.oneOf(['male', 'female']).assert(1) => false

如果一个变量的类型,可能是undefined,可能是string,该如何表示?

使用maybe

duckie.maybe(String).assert('hello') => true
duckie.maybe(String).assert(undefined) => true
duckie.maybe(String).assert(123) => false/*注:String可替换为duckie.string或"string",意义都一样*/

如果一个变量的类型可能是string,可能是number呢?

使用oneOfType

duckie.oneOfType([String, Number]).assert(1) => true
duckie.oneOfType([String, Number]).assert("hello") => true
duckie.oneOfType([String, Number]).assert(true) => false

如果一个变量是一个由数字组成的数组,该如何表示?

使用arrayOf(Number),或[Number].

// 使用arrayOf
duckie.arrayOf(Number).assert([1,2,3]) => true
// 直接使用[/*类型*/]
duckie([Number]).assert([1,2,3]) => true
duckie(['number']).assert(['hello', 'world']) => false/* 注: 类型声明使用Number,duckie.number 和 'number' 效果是一样的。*/

如果一个变量是由一些key:value组成呢?

使用objectOf,或[].

//例如定义一个Person数据结构,典型的变量如下:
var person = {name: 'jack',age: 18
};duckie.objectOf({name: String,age: Number
}).assert(person) => trueduckie({name: String,age: Number
}).assert(person) => true// 鸭子断言,即只要求被断言对象符合定义的
// 键值类型要求,而不要求精确匹配键数量
duckie({name: String
}).assert(person) => trueduckie({name: Number
}).assert(person) => false

如果一个变量是个object,里面有些值是数组呢?

以声明变量的方式用duckie声明你的类型。

// 比如篇首这东西
var person = {name: "jack",age: 18,address: {country: 'china',city: 'beijing'},keywords: ['student', 'programmer', 'ios']
}// 使用duckie声明
duckie({name: String,age: Number,address: {country: String,city: String},keywords: [String]
}).assert(person) => true

声明一个类型跟声明一个对象般简单,完全没有学习成本。

总结

使用duckie可以像声明一个变量那样声明你的类型,且可以在运行时进行类型检查。如有什么建议,欢迎提议。



推荐阅读
  • Vue cli2.0 项目中使用Monaco Editor编辑器
    monaco-editor是微软出的一条开源web在线编辑器支持多种语言,代码高亮,代码提示等功能,与VisualStudioCode功能几乎相同。在项目中可能会用带代码编 ... [详细]
  • Android Studio Bumblebee | 2021.1.1(大黄蜂版本使用介绍)
    本文介绍了Android Studio Bumblebee | 2021.1.1(大黄蜂版本)的使用方法和相关知识,包括Gradle的介绍、设备管理器的配置、无线调试、新版本问题等内容。同时还提供了更新版本的下载地址和启动页面截图。 ... [详细]
  • CF:3D City Model(小思维)问题解析和代码实现
    本文通过解析CF:3D City Model问题,介绍了问题的背景和要求,并给出了相应的代码实现。该问题涉及到在一个矩形的网格上建造城市的情景,每个网格单元可以作为建筑的基础,建筑由多个立方体叠加而成。文章详细讲解了问题的解决思路,并给出了相应的代码实现供读者参考。 ... [详细]
  • C++字符字符串处理及字符集编码方案
    本文介绍了C++中字符字符串处理的问题,并详细解释了字符集编码方案,包括UNICODE、Windows apps采用的UTF-16编码、ASCII、SBCS和DBCS编码方案。同时说明了ANSI C标准和Windows中的字符/字符串数据类型实现。文章还提到了在编译时需要定义UNICODE宏以支持unicode编码,否则将使用windows code page编译。最后,给出了相关的头文件和数据类型定义。 ... [详细]
  • 3.223.28周学习总结中的贪心作业收获及困惑
    本文是对3.223.28周学习总结中的贪心作业进行总结,作者在解题过程中参考了他人的代码,但前提是要先理解题目并有解题思路。作者分享了自己在贪心作业中的收获,同时提到了一道让他困惑的题目,即input details部分引发的疑惑。 ... [详细]
  • 本文介绍了在使用vue和webpack进行异步组件按需加载时可能出现的报错问题,并提供了解决方法。同时还解答了关于局部注册组件和v-if指令的相关问题。 ... [详细]
  • 本文介绍了iOS数据库Sqlite的SQL语句分类和常见约束关键字。SQL语句分为DDL、DML和DQL三种类型,其中DDL语句用于定义、删除和修改数据表,关键字包括create、drop和alter。常见约束关键字包括if not exists、if exists、primary key、autoincrement、not null和default。此外,还介绍了常见的数据库数据类型,包括integer、text和real。 ... [详细]
  • 本文介绍了一个适用于PHP应用快速接入TRX和TRC20数字资产的开发包,该开发包支持使用自有Tron区块链节点的应用场景,也支持基于Tron官方公共API服务的轻量级部署场景。提供的功能包括生成地址、验证地址、查询余额、交易转账、查询最新区块和查询交易信息等。详细信息可参考tron-php的Github地址:https://github.com/Fenguoz/tron-php。 ... [详细]
  • VueCLI多页分目录打包的步骤记录
    本文介绍了使用VueCLI进行多页分目录打包的步骤,包括页面目录结构、安装依赖、获取Vue CLI需要的多页对象等内容。同时还提供了自定义不同模块页面标题的方法。 ... [详细]
  • loader资源模块加载器webpack资源模块加载webpack内部(内部loader)默认只会处理javascript文件,也就是说它会把打包过程中所有遇到的 ... [详细]
  • Linux服务器密码过期策略、登录次数限制、私钥登录等配置方法
    本文介绍了在Linux服务器上进行密码过期策略、登录次数限制、私钥登录等配置的方法。通过修改配置文件中的参数,可以设置密码的有效期、最小间隔时间、最小长度,并在密码过期前进行提示。同时还介绍了如何进行公钥登录和修改默认账户用户名的操作。详细步骤和注意事项可参考本文内容。 ... [详细]
  • 本文介绍了MyBioSource转甲状腺素蛋白定量检测ELISA试剂盒的应用方法及特点。ELISA法作为一项新技术在免疫诊断中的应用范围不断扩大,不仅适用于多种病原微生物引起的传染病、非传染病的免疫诊断,也可用于大/小分子抗原的定量检测。ELISA法具有灵敏、特异、简单、快速、稳定及易于自动化操作等特点,是一种早期诊断的良好方法,也可用于血清流行病学调查。MyBioSource转甲状腺素蛋白定量检测ELISA试剂盒使用方法包括对血清和血浆的操作要求。 ... [详细]
  • 本文介绍了P1651题目的描述和要求,以及计算能搭建的塔的最大高度的方法。通过动态规划和状压技术,将问题转化为求解差值的问题,并定义了相应的状态。最终得出了计算最大高度的解法。 ... [详细]
  • 本文介绍了解决二叉树层序创建问题的方法。通过使用队列结构体和二叉树结构体,实现了入队和出队操作,并提供了判断队列是否为空的函数。详细介绍了解决该问题的步骤和流程。 ... [详细]
  • 使用npmi编译vue项目出现无法下载github.com中的对应的包源文件报错信息如下:npmERR!fatal:unabletoaccess'https:github ... [详细]
author-avatar
手机用户2502929967
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有