做一个自己的JS运行时数据类型检查工具

广告位招租
扫码页面底部二维码联系

JS是一个动态数据类型的语言,所谓动态数著作权归作者所有,禁止商业用途转载。【本文受版权保护】据类型,是指在程序运行过程中,一个变量的原创内容,盗版必究。著作权归作者所有,禁止商业用途转载。数据类型可以随时改变。这有好处也有坏处,【版权所有,侵权必究】【版权所有,侵权必究】好处是灵活性,坏处不言而喻,就是输入输出【关注微信公众号:wwwtangshuangnet】本文作者:唐霜,转载请注明出处。的不可控。为了解决这个问题,TypeSc未经授权,禁止复制转载。【原创内容,转载请注明出处】ript应运而生,它可以通过撰写数据类型本文版权归作者所有,未经授权不得转载。【作者:唐霜】的接口、范型等,对程序中的数据类型做一个本文版权归作者所有,未经授权不得转载。本文版权归作者所有,未经授权不得转载。规定,在编译时,根据代码的上下文对这些类【原创内容,转载请注明出处】本文作者:唐霜,转载请注明出处。型进行检查,比如你声明了一个原本为数值型本文版权归作者所有,未经授权不得转载。原创内容,盗版必究。的变量,想要传入到一个规定为字符型参数的本文作者:唐霜,转载请注明出处。【原创不易,请尊重版权】函数中,编译时就会提示错误。

【作者:唐霜】【版权所有】唐霜 www.tangshuang.net【版权所有】唐霜 www.tangshuang.net【未经授权禁止转载】【关注微信公众号:wwwtangshuangnet】

但是TypeScript无法做到运行时数【版权所有,侵权必究】【本文首发于唐霜的博客】据类型检查。运行时数据类型问题主要是在和本文版权归作者所有,未经授权不得转载。【本文首发于唐霜的博客】api接口交互时发生,比方说,有个接口要【原创内容,转载请注明出处】【版权所有】唐霜 www.tangshuang.net求一定要有哪些字段,即使为空也行,也比如【未经授权禁止转载】未经授权,禁止复制转载。,有些接口返回的格式和你本地代码预期的格【原创内容,转载请注明出处】原创内容,盗版必究。式不同,或者数据类型不一样,你预期得到一【未经授权禁止转载】【版权所有,侵权必究】个数字,但是接口返回给你的是这个数字的字原创内容,盗版必究。原创内容,盗版必究。符串形式。

转载请注明出处:www.tangshuang.net未经授权,禁止复制转载。【本文首发于唐霜的博客】【原创不易,请尊重版权】

为了解决运行时数据类型的问题,我写了he【本文受版权保护】转载请注明出处:www.tangshuang.netllo-type这个包。(看来我要把he转载请注明出处:www.tangshuang.net【版权所有】唐霜 www.tangshuang.netllo系列坚持到底了。)

【关注微信公众号:wwwtangshuangnet】本文版权归作者所有,未经授权不得转载。【关注微信公众号:wwwtangshuangnet】原创内容,盗版必究。

想法转载请注明出处:www.tangshuang.net

本文版权归作者所有,未经授权不得转载。未经授权,禁止复制转载。原创内容,盗版必究。未经授权,禁止复制转载。

如何解决运行时的类型(甚至是object【访问 www.tangshuang.net 获取更多精彩内容】【版权所有,侵权必究】的格式)检查呢?在比较原始的编程习惯里面著作权归作者所有,禁止商业用途转载。【版权所有,侵权必究】,是在业务代码里面实时进行检查,比如:

本文版权归作者所有,未经授权不得转载。原创内容,盗版必究。【本文受版权保护】本文版权归作者所有,未经授权不得转载。【作者:唐霜】
fetch(api_url).then(res => res.json()).then((data) => {
  if (typeof data === 'object' && data.code === 0) {
    // 表明正常返回数据
  }
  if (Array.isArray(data.list)) {
    data.list.forEach((item) => {
      // 利用列表进行下一步操作
    })
  }
})

但是很显然,这样做的不足之处在于:1.需本文作者:唐霜,转载请注明出处。【未经授权禁止转载】要在每处业务代码里面进行检查,耗时耗力,【访问 www.tangshuang.net 获取更多精彩内容】【版权所有,侵权必究】而且可能会出现重复代码;2.对于特定的数【版权所有,侵权必究】著作权归作者所有,禁止商业用途转载。据,可能会出现很多if嵌套的问题。

【关注微信公众号:wwwtangshuangnet】【未经授权禁止转载】【版权所有,侵权必究】

于是我想,针对第一点,只要写出一个数据检著作权归作者所有,禁止商业用途转载。本文作者:唐霜,转载请注明出处。查工具,在要进行数据检查时调用某些接口就本文版权归作者所有,未经授权不得转载。本文版权归作者所有,未经授权不得转载。好了,不必重复写逻辑。针对第二点,能不能转载请注明出处:www.tangshuang.net【转载请注明来源】让这个工具支持object嵌套检查?

本文版权归作者所有,未经授权不得转载。著作权归作者所有,禁止商业用途转载。【版权所有】唐霜 www.tangshuang.net著作权归作者所有,禁止商业用途转载。

出于这种想法。我先写下了我希望这个工具的著作权归作者所有,禁止商业用途转载。原创内容,盗版必究。代码怎么去写(说到这里,我们在开发一个工【原创不易,请尊重版权】本文作者:唐霜,转载请注明出处。具的时候,不必马上去写工具本身的实现代码【版权所有,侵权必究】转载请注明出处:www.tangshuang.net,可以反过来,先把我要怎么使用这个工具的原创内容,盗版必究。【未经授权禁止转载】代码先写出来,然后按照写出来的这些规则方原创内容,盗版必究。【版权所有,侵权必究】式去实现)。

【版权所有】唐霜 www.tangshuang.net本文作者:唐霜,转载请注明出处。【未经授权禁止转载】本文作者:唐霜,转载请注明出处。【未经授权禁止转载】
// 我想要对含有name和age的object进行检查,要求name是字符串,而age必须是数字
const PersonType = new Type({
  name: String,
  age: Number,
})
// 接下来用SomeType去进行数据类型判断

和TypeScript不同,因为我要实现【版权所有】唐霜 www.tangshuang.net转载请注明出处:www.tangshuang.net的工具完全就是ES的语法,TypeScr【关注微信公众号:wwwtangshuangnet】【版权所有,侵权必究】ipt可以自己制造语法,比如interf【版权所有】唐霜 www.tangshuang.net原创内容,盗版必究。ace之类的,但是我的代码是在运行时执行【版权所有】唐霜 www.tangshuang.net【访问 www.tangshuang.net 获取更多精彩内容】的,所以不能自己造语法,只能利用ES语法本文作者:唐霜,转载请注明出处。著作权归作者所有,禁止商业用途转载。,写出一种模式。最初,我想用name: 'string'这种形式,但是这就意味着我要自己定义每一转载请注明出处:www.tangshuang.net【未经授权禁止转载】种数据类型的实际意义,因为’著作权归作者所有,禁止商业用途转载。著作权归作者所有,禁止商业用途转载。string’这个字符串,虽【关注微信公众号:wwwtangshuangnet】【版权所有,侵权必究】然字面意思是字符串,但我内部可以认为它是【未经授权禁止转载】未经授权,禁止复制转载。另一种形式。而且,这样的话,我无法做到两【作者:唐霜】【版权所有】唐霜 www.tangshuang.net件事:a)假如我想规定某个变量的值只能是【作者:唐霜】【本文受版权保护】字符串’stringR未经授权,禁止复制转载。【转载请注明来源】17;,我该怎么办?b)假如我希望检查某【版权所有,侵权必究】本文作者:唐霜,转载请注明出处。个变量是否是另一种数据类型(某个类的实例【未经授权禁止转载】【作者:唐霜】)怎么办?考虑到java里面自己规定数据本文版权归作者所有,未经授权不得转载。未经授权,禁止复制转载。类型的前车之鉴,我直接用js里面现有的一本文版权归作者所有,未经授权不得转载。未经授权,禁止复制转载。些接口作为数据类型检查的规则。

【版权所有,侵权必究】【作者:唐霜】【原创内容,转载请注明出处】【版权所有】唐霜 www.tangshuang.net【转载请注明来源】

怎么进行检查呢?我想来想去,想到了前端单【未经授权禁止转载】【访问 www.tangshuang.net 获取更多精彩内容】元测试里面的语法,主要有assert, 本文版权归作者所有,未经授权不得转载。本文作者:唐霜,转载请注明出处。expect, should这类于是我想原创内容,盗版必究。【访问 www.tangshuang.net 获取更多精彩内容】,干脆采用这种方式比较好,让数据类型检查【版权所有,侵权必究】【原创不易,请尊重版权】和单元测试一样,而且它们感觉上也非常接近本文作者:唐霜,转载请注明出处。本文作者:唐霜,转载请注明出处。,于是:

【作者:唐霜】转载请注明出处:www.tangshuang.net【访问 www.tangshuang.net 获取更多精彩内容】
PersonType.assert(person)

把上面这段代码放在函数的开头,对函数的参【关注微信公众号:wwwtangshuangnet】本文作者:唐霜,转载请注明出处。数person进行检查,如果person著作权归作者所有,禁止商业用途转载。【作者:唐霜】的格式和内部字段的数据类型不符合,就直接【作者:唐霜】原创内容,盗版必究。抛出错误,这样,函数就不会被执行。

【版权所有】唐霜 www.tangshuang.net未经授权,禁止复制转载。【版权所有】唐霜 www.tangshuang.net

在很多文章里面指出,最好不要在代码里面使【本文受版权保护】【未经授权禁止转载】用throw new Error这个模式【未经授权禁止转载】未经授权,禁止复制转载。抛出错误。我的观点则相反,throw出来【访问 www.tangshuang.net 获取更多精彩内容】著作权归作者所有,禁止商业用途转载。的错误非常有利于debug,而且可以通过著作权归作者所有,禁止商业用途转载。著作权归作者所有,禁止商业用途转载。window.onerror对错误信息进【访问 www.tangshuang.net 获取更多精彩内容】转载请注明出处:www.tangshuang.net行收集,将收集后的错误信息发送到服务端进本文版权归作者所有,未经授权不得转载。【本文受版权保护】行分析。而且,从另外一个角度来看,thr原创内容,盗版必究。【作者:唐霜】ow出来的错误,是可以被catch的,对转载请注明出处:www.tangshuang.net【未经授权禁止转载】于编程而言,如果确实需要对throw型错原创内容,盗版必究。【原创内容,转载请注明出处】误做进一步判别,可以通过catch捕获,本文版权归作者所有,未经授权不得转载。未经授权,禁止复制转载。根据捕获到的信息决定是否要继续程序往下执【关注微信公众号:wwwtangshuangnet】本文版权归作者所有,未经授权不得转载。行。

本文版权归作者所有,未经授权不得转载。原创内容,盗版必究。【转载请注明来源】本文版权归作者所有,未经授权不得转载。原创内容,盗版必究。
PersonType.test(person)

这个方法则主要用于判断,返回一个bool原创内容,盗版必究。【原创不易,请尊重版权】ean结果,这肯定是需要的,在很多情况下【转载请注明来源】原创内容,盗版必究。,开发者自己根据数据类型是否符合预期,自【版权所有,侵权必究】【访问 www.tangshuang.net 获取更多精彩内容】己决定该让程序如何走向。

【作者:唐霜】【转载请注明来源】【未经授权禁止转载】
PersonType.trace(person).with(fn)

这个方法则在执行到这个位置的时候啥也不干本文作者:唐霜,转载请注明出处。【版权所有】唐霜 www.tangshuang.net,只是对person这个变量进行数据类型本文作者:唐霜,转载请注明出处。本文版权归作者所有,未经授权不得转载。追踪,并且通过with传入的函数捕获可能转载请注明出处:www.tangshuang.net著作权归作者所有,禁止商业用途转载。发现的不符合要求而抛出的错误。而且它真的本文作者:唐霜,转载请注明出处。转载请注明出处:www.tangshuang.net是完全的异步,所谓完全的异步,和Prom本文版权归作者所有,未经授权不得转载。【作者:唐霜】ise的默认表现都不一样,Promise【本文首发于唐霜的博客】【本文受版权保护】会在一开始被调用时,执行传给它的函数,但【本文首发于唐霜的博客】本文作者:唐霜,转载请注明出处。这里的trace方法,完全是在异步环境下转载请注明出处:www.tangshuang.net【原创不易,请尊重版权】去做的。不过有一个点就是,在函数内部,决本文作者:唐霜,转载请注明出处。转载请注明出处:www.tangshuang.net不允许修改person这个变量的属性,你本文作者:唐霜,转载请注明出处。【未经授权禁止转载】不能传进来的时候person.name 【作者:唐霜】转载请注明出处:www.tangshuang.net= 12344,但是在函数执行过程中又改本文版权归作者所有,未经授权不得转载。未经授权,禁止复制转载。为person.name = ̵【版权所有】唐霜 www.tangshuang.net未经授权,禁止复制转载。6;xxx’,这种改动会导致原创内容,盗版必究。【原创内容,转载请注明出处】追踪不准确。

未经授权,禁止复制转载。【转载请注明来源】【关注微信公众号:wwwtangshuangnet】【本文首发于唐霜的博客】【作者:唐霜】

不过这种方式就要求用户异步捕获,而不能在【转载请注明来源】著作权归作者所有,禁止商业用途转载。检查报错时即时进行调整,而assert方【版权所有】唐霜 www.tangshuang.net【版权所有】唐霜 www.tangshuang.net法又会阻断程序,test方法又不能获得报【版权所有,侵权必究】【转载请注明来源】错的内容和追踪信息,于是需要提供一个同步本文作者:唐霜,转载请注明出处。【本文受版权保护】的方法,返回检查报错信息:

本文版权归作者所有,未经授权不得转载。未经授权,禁止复制转载。【本文首发于唐霜的博客】著作权归作者所有,禁止商业用途转载。转载请注明出处:www.tangshuang.net
let error = PersonType.catch(person)
if (error) {
  // error是一个new Error
  // 检查到传入的person不符合PersonType
  // 开发者在这里可以做一些异常提示的界面,但不阻断程序继续
}

我有想过在trace被调用的时候进行pe【版权所有】唐霜 www.tangshuang.net著作权归作者所有,禁止商业用途转载。rson的deep clone,但是后来【原创不易,请尊重版权】【访问 www.tangshuang.net 获取更多精彩内容】觉得太消耗资源,异步的目的反而不能达到。

原创内容,盗版必究。未经授权,禁止复制转载。本文版权归作者所有,未经授权不得转载。未经授权,禁止复制转载。

以上就是我一开始的想法,在后来的代码撰写【版权所有】唐霜 www.tangshuang.net本文版权归作者所有,未经授权不得转载。里面,慢慢又加入了新想法,比如ES7的装原创内容,盗版必究。著作权归作者所有,禁止商业用途转载。饰器方式调用,或者用一个更加统一的方式调原创内容,盗版必究。【版权所有】唐霜 www.tangshuang.net用,这样当我进行代码检查的时候,直接用编【作者:唐霜】本文版权归作者所有,未经授权不得转载。辑器的搜索功能就可以找到所有进行类型断言【原创内容,转载请注明出处】【关注微信公众号:wwwtangshuangnet】的代码:

【关注微信公众号:wwwtangshuangnet】转载请注明出处:www.tangshuang.net【原创不易,请尊重版权】【未经授权禁止转载】
HelloType.expect(PersonType).toBe.typeof(person)

就像一个全局的调用一样,非常好看,所有的著作权归作者所有,禁止商业用途转载。本文作者:唐霜,转载请注明出处。代码都可以得到统一,比PersonTyp本文作者:唐霜,转载请注明出处。【访问 www.tangshuang.net 获取更多精彩内容】e.assert()的方式漂亮多了。

【转载请注明来源】未经授权,禁止复制转载。本文作者:唐霜,转载请注明出处。

基本类型【访问 www.tangshuang.net 获取更多精彩内容】

本文作者:唐霜,转载请注明出处。【原创不易,请尊重版权】转载请注明出处:www.tangshuang.net【访问 www.tangshuang.net 获取更多精彩内容】【访问 www.tangshuang.net 获取更多精彩内容】

有了想法之后,开始开发基本的类型容器。和著作权归作者所有,禁止商业用途转载。【转载请注明来源】前面的new Type一样,可以创建一个【关注微信公众号:wwwtangshuangnet】【关注微信公众号:wwwtangshuangnet】数据类型,这个数据类型的容器拥有一系列方【版权所有,侵权必究】本文版权归作者所有,未经授权不得转载。法,也就是上面提到的那些,利用这些方法,【版权所有,侵权必究】未经授权,禁止复制转载。就可以去检查某个具体的变量是否是这个数据未经授权,禁止复制转载。【本文受版权保护】类型。

【原创不易,请尊重版权】未经授权,禁止复制转载。【原创内容,转载请注明出处】【关注微信公众号:wwwtangshuangnet】未经授权,禁止复制转载。
const SomeType = new Type({
  name: String,
  age: Number,
})

let obj = {
  name: 'tomy',
  age: 10,
}

SomeType.test(obj) // true

let yep = {
  name: 'dota',
  height: 123,
}
SomeType.test(yep) // false

let doge = {
  name: 'gofi',
  age: 'unknow',
}
SomeType.test(doge) // false

Type接受任意的内容,比如你可以传入一【本文受版权保护】【访问 www.tangshuang.net 获取更多精彩内容】个Number或String形成一个单独本文版权归作者所有,未经授权不得转载。【未经授权禁止转载】的值:

未经授权,禁止复制转载。本文版权归作者所有,未经授权不得转载。著作权归作者所有,禁止商业用途转载。【本文受版权保护】【转载请注明来源】
const NumberType = new Type(Number)

之所以做这种看上去傻的事,是因为你现在可【版权所有,侵权必究】【作者:唐霜】以用NumberType检查一个变量是否原创内容,盗版必究。【本文首发于唐霜的博客】为数字。

原创内容,盗版必究。【访问 www.tangshuang.net 获取更多精彩内容】【版权所有,侵权必究】【访问 www.tangshuang.net 获取更多精彩内容】

也可以传入嵌套的对象,这样,在检查的时候著作权归作者所有,禁止商业用途转载。【版权所有,侵权必究】,还会进行嵌套检查,如果深层嵌套位置的类【原创不易,请尊重版权】【版权所有,侵权必究】型不匹配,也会抛出错误:

【关注微信公众号:wwwtangshuangnet】【本文首发于唐霜的博客】【版权所有】唐霜 www.tangshuang.net【原创内容,转载请注明出处】未经授权,禁止复制转载。
const SomeType = new Type({
  name: String,
  body: {
    head: Object,
    foot: {
      count: Number,
      size: String,
    },
  }
})

你可以看到,SomeType这个类型规定【原创不易,请尊重版权】未经授权,禁止复制转载。了三层的嵌套模型,如果你检查的objec本文版权归作者所有,未经授权不得转载。【版权所有,侵权必究】t不符合这样的模型结构,就会抛出错误,而著作权归作者所有,禁止商业用途转载。未经授权,禁止复制转载。且,即使模型结构符合,底层的某一个类型不著作权归作者所有,禁止商业用途转载。【未经授权禁止转载】符合,也会抛出错误。

【原创不易,请尊重版权】【访问 www.tangshuang.net 获取更多精彩内容】原创内容,盗版必究。【未经授权禁止转载】转载请注明出处:www.tangshuang.net

另外,自己创建的类型,可以被其他类型创建未经授权,禁止复制转载。著作权归作者所有,禁止商业用途转载。时引用:

转载请注明出处:www.tangshuang.net【版权所有】唐霜 www.tangshuang.net【作者:唐霜】【原创内容,转载请注明出处】
const BookType = new Type({
  name: String,
  author: String,
})
const RoomType = new Type({
  book: BookType,
  desc: String,
})

在内部实现的时候,如果遇到一个数据类型是【本文受版权保护】著作权归作者所有,禁止商业用途转载。Type的实例的话,就调用这个实例对该节本文作者:唐霜,转载请注明出处。【版权所有,侵权必究】点的值进行检查,这样就可以做到层层嵌套。

【关注微信公众号:wwwtangshuangnet】未经授权,禁止复制转载。【原创不易,请尊重版权】

不过,目前我还不能实现自引用,因为js在【原创不易,请尊重版权】本文版权归作者所有,未经授权不得转载。一个变量声明的时候,是无法使用自己已经完【原创内容,转载请注明出处】著作权归作者所有,禁止商业用途转载。成的定义的。

【本文受版权保护】【未经授权禁止转载】原创内容,盗版必究。本文版权归作者所有,未经授权不得转载。

扩展类型著作权归作者所有,禁止商业用途转载。

本文版权归作者所有,未经授权不得转载。【关注微信公众号:wwwtangshuangnet】著作权归作者所有,禁止商业用途转载。

我总共扩展出五种类型:Dict, Lis【原创内容,转载请注明出处】【原创不易,请尊重版权】t, Tuple, Enum, Rang【访问 www.tangshuang.net 获取更多精彩内容】【未经授权禁止转载】e。

著作权归作者所有,禁止商业用途转载。【转载请注明来源】转载请注明出处:www.tangshuang.net未经授权,禁止复制转载。

先来看下它们的使用方法:未经授权,禁止复制转载。

【版权所有】唐霜 www.tangshuang.net【未经授权禁止转载】【作者:唐霜】【本文受版权保护】【作者:唐霜】
const DictType = Dict({ name: String })
const ListType = List(Number)
const TupleType = Tuple(Object, ListType)
const EnumType = Enum('red', 'blue', 'yellow')
const RangeType = Range(0, 1)

这几个类型都是通过上面的函数实现创建的。

原创内容,盗版必究。【本文受版权保护】【访问 www.tangshuang.net 获取更多精彩内容】本文版权归作者所有,未经授权不得转载。【原创不易,请尊重版权】
  • Dict(字典)类型实质就是对应obje著作权归作者所有,禁止商业用途转载。转载请注明出处:www.tangshuang.netct,只是一种更简便的写法。
  • 著作权归作者所有,禁止商业用途转载。【本文首发于唐霜的博客】著作权归作者所有,禁止商业用途转载。【版权所有】唐霜 www.tangshuang.net
  • List(列表)类型对应的是数组,但是它【原创不易,请尊重版权】【版权所有】唐霜 www.tangshuang.net要求数组的每一个元素具有相同的数据类型。
  • 【本文首发于唐霜的博客】原创内容,盗版必究。著作权归作者所有,禁止商业用途转载。本文版权归作者所有,未经授权不得转载。
  • Tuple(元组)在js里面没有,它要求【作者:唐霜】本文版权归作者所有,未经授权不得转载。传入的一组变量具有固定顺序和固定个数,每原创内容,盗版必究。本文版权归作者所有,未经授权不得转载。一个元素类型可以不同。
  • 【未经授权禁止转载】【未经授权禁止转载】本文版权归作者所有,未经授权不得转载。转载请注明出处:www.tangshuang.net
  • Enum(枚举)在js里面也没有,它要求【版权所有,侵权必究】未经授权,禁止复制转载。传入的变量的值只允许从规定的几个值中间进本文作者:唐霜,转载请注明出处。未经授权,禁止复制转载。行选择。
  • 【关注微信公众号:wwwtangshuangnet】【版权所有】唐霜 www.tangshuang.net本文作者:唐霜,转载请注明出处。
  • Range(值域)传入两个值,一个最大值【原创不易,请尊重版权】【版权所有】唐霜 www.tangshuang.net,一个最小值,如果要用来断言的数值在这个本文版权归作者所有,未经授权不得转载。著作权归作者所有,禁止商业用途转载。区间,就通过
  • 【版权所有】唐霜 www.tangshuang.net【未经授权禁止转载】【原创不易,请尊重版权】【本文首发于唐霜的博客】

Dict和js原生的Object有区别,【版权所有】唐霜 www.tangshuang.net【版权所有,侵权必究】原生的Object只要求顶层是一个纯对象原创内容,盗版必究。【原创内容,转载请注明出处】即可,而Dict则会对对象的里面结构以及原创内容,盗版必究。【转载请注明来源】属性的类型进行检查。List和原生的Ar转载请注明出处:www.tangshuang.net原创内容,盗版必究。ray的区别是,Array里面的每个元素本文版权归作者所有,未经授权不得转载。【版权所有】唐霜 www.tangshuang.net的类型是随意的,只要满足顶层是数组就通过【本文首发于唐霜的博客】未经授权,禁止复制转载。,而List不仅要求数组里面每个对应元素著作权归作者所有,禁止商业用途转载。【版权所有】唐霜 www.tangshuang.net是相同数据类型,而且还会对每一个元素内部转载请注明出处:www.tangshuang.net【版权所有】唐霜 www.tangshuang.net的结构进行检查。

【原创不易,请尊重版权】本文版权归作者所有,未经授权不得转载。本文作者:唐霜,转载请注明出处。【本文受版权保护】著作权归作者所有,禁止商业用途转载。

当然了,它们都是可以嵌套的,所以,和基本著作权归作者所有,禁止商业用途转载。转载请注明出处:www.tangshuang.net类型new Type组合起来,你可以创造【转载请注明来源】【原创不易,请尊重版权】出任何形式的数据类型检查。

著作权归作者所有,禁止商业用途转载。著作权归作者所有,禁止商业用途转载。未经授权,禁止复制转载。【未经授权禁止转载】

检查规则【原创不易,请尊重版权】

【本文首发于唐霜的博客】【版权所有】唐霜 www.tangshuang.net【关注微信公众号:wwwtangshuangnet】【原创内容,转载请注明出处】

数据类型也有了,拿到数据,如何验证数据与【版权所有,侵权必究】未经授权,禁止复制转载。类型是否相符呢?对于开发者,可以不用深入本文版权归作者所有,未经授权不得转载。【作者:唐霜】追究,但是这里作为探讨,可以把一些内部的著作权归作者所有,禁止商业用途转载。【转载请注明来源】方法拿来讨论一下。

著作权归作者所有,禁止商业用途转载。【转载请注明来源】【版权所有】唐霜 www.tangshuang.net本文作者:唐霜,转载请注明出处。【版权所有,侵权必究】

比如,NumberType.assert【原创内容,转载请注明出处】未经授权,禁止复制转载。(12)怎么确定是通过NumberTyp【原创不易,请尊重版权】【关注微信公众号:wwwtangshuangnet】e.assert(‘xx&#【版权所有】唐霜 www.tangshuang.net【作者:唐霜】8217;)怎么确定不符合?其实很简单:

【本文受版权保护】未经授权,禁止复制转载。【原创不易,请尊重版权】【关注微信公众号:wwwtangshuangnet】
  1. 在new Type的时候把期望数据类型存著作权归作者所有,禁止商业用途转载。【访问 www.tangshuang.net 获取更多精彩内容】起来
  2. 转载请注明出处:www.tangshuang.net本文版权归作者所有,未经授权不得转载。原创内容,盗版必究。
  3. assert的时候,取出来,进行对比即可
  4. 【访问 www.tangshuang.net 获取更多精彩内容】【版权所有,侵权必究】【未经授权禁止转载】

但是js原生的数据类型有很多坑,例如&#【作者:唐霜】未经授权,禁止复制转载。8217;xxx’ inst【原创内容,转载请注明出处】原创内容,盗版必究。anceof String是false,原创内容,盗版必究。【版权所有,侵权必究】new Boolean(true) !=本文版权归作者所有,未经授权不得转载。本文作者:唐霜,转载请注明出处。= true,typeof NaN为nu【本文首发于唐霜的博客】原创内容,盗版必究。mber等等。因此,要在内部实现的时候,【本文首发于唐霜的博客】本文版权归作者所有,未经授权不得转载。把这些js里面的坑都填平。

【本文受版权保护】本文作者:唐霜,转载请注明出处。【原创不易,请尊重版权】【版权所有】唐霜 www.tangshuang.net

对于嵌套的object的类型检查则要复杂【本文首发于唐霜的博客】【访问 www.tangshuang.net 获取更多精彩内容】一些,我需要把所有列出来的层级的路径算出【访问 www.tangshuang.net 获取更多精彩内容】【本文首发于唐霜的博客】来,再和传入的变量的路径去对比,并且要保【作者:唐霜】未经授权,禁止复制转载。证路径对应的类型相同。

【本文首发于唐霜的博客】转载请注明出处:www.tangshuang.net【版权所有】唐霜 www.tangshuang.net【本文受版权保护】【版权所有】唐霜 www.tangshuang.net

自定义规则转载请注明出处:www.tangshuang.net

【关注微信公众号:wwwtangshuangnet】未经授权,禁止复制转载。【未经授权禁止转载】本文作者:唐霜,转载请注明出处。

为了增加灵活性,我还提供自定义规则的能力本文版权归作者所有,未经授权不得转载。【未经授权禁止转载】,不过需要借助一个Rule构造器,通过传著作权归作者所有,禁止商业用途转载。本文作者:唐霜,转载请注明出处。入一个处理函数来进行判别,比如我想检查一原创内容,盗版必究。【版权所有,侵权必究】个值是否只要typeof为object即原创内容,盗版必究。【原创内容,转载请注明出处】可:

【关注微信公众号:wwwtangshuangnet】【原创不易,请尊重版权】【关注微信公众号:wwwtangshuangnet】【转载请注明来源】【关注微信公众号:wwwtangshuangnet】
const ObjectRule = new Rule(function(value) {
  return typeof value === 'object'
})

然后用这个rule作为类型进行传入:未经授权,禁止复制转载。

【本文受版权保护】本文版权归作者所有,未经授权不得转载。【作者:唐霜】
const MyType = new Type({
  a: ObjectRule,
})

这样,在用MyType进行检查的时候,就【关注微信公众号:wwwtangshuangnet】【未经授权禁止转载】能使用自己创建的一个检查规则来对数据类型未经授权,禁止复制转载。著作权归作者所有,禁止商业用途转载。进行检查。注意,ObjectRule不是【版权所有,侵权必究】本文作者:唐霜,转载请注明出处。数据类型,没有assert等方法,不具备【原创不易,请尊重版权】转载请注明出处:www.tangshuang.net对值进行检查的能力。

本文作者:唐霜,转载请注明出处。【本文受版权保护】【原创内容,转载请注明出处】未经授权,禁止复制转载。著作权归作者所有,禁止商业用途转载。

HelloType【本文受版权保护】

【本文受版权保护】原创内容,盗版必究。转载请注明出处:www.tangshuang.net本文版权归作者所有,未经授权不得转载。【本文首发于唐霜的博客】

经过几天的撰写,这个工具就写完了,名字取【访问 www.tangshuang.net 获取更多精彩内容】本文版权归作者所有,未经授权不得转载。名HelloType纯粹是因为我已经写了【版权所有】唐霜 www.tangshuang.net【本文首发于唐霜的博客】好几个hello系列的包了,实在找不到要【版权所有,侵权必究】转载请注明出处:www.tangshuang.net怎么取名,就用这种浅显易懂的名字比较好。【版权所有,侵权必究】【版权所有,侵权必究】你可以在这里读到它的说明文档【关注微信公众号:wwwtangshuangnet】,本文就不详细介绍了,只说一些我觉得需要【访问 www.tangshuang.net 获取更多精彩内容】转载请注明出处:www.tangshuang.net说的东西。

【版权所有】唐霜 www.tangshuang.net【原创内容,转载请注明出处】转载请注明出处:www.tangshuang.net

使用HelloType进行数据检查要分两原创内容,盗版必究。【访问 www.tangshuang.net 获取更多精彩内容】步走,第一步是创建数据类型,第二部是调用【版权所有,侵权必究】原创内容,盗版必究。数据类型容器的方法进行检查。在编程上第一原创内容,盗版必究。【原创不易,请尊重版权】步的代码会比较多,如果写在业务代码里面,【原创内容,转载请注明出处】【转载请注明来源】反而和文章最前面说的那种情况没有两样,除【本文首发于唐霜的博客】【未经授权禁止转载】非是即时检查,比如突然兴起,写一个:

【关注微信公众号:wwwtangshuangnet】【转载请注明来源】【原创内容,转载请注明出处】
(new Type(Number)).assert(arg)

这还可以接受,但是如果想大面积的确定一些著作权归作者所有,禁止商业用途转载。著作权归作者所有,禁止商业用途转载。类型,比较好的建议,还是专门设立一个文件【访问 www.tangshuang.net 获取更多精彩内容】转载请注明出处:www.tangshuang.net(夹)把数据类型的创建都放在这些文件里面【原创内容,转载请注明出处】本文作者:唐霜,转载请注明出处。,在具体的业务代码里面import进来,【版权所有】唐霜 www.tangshuang.net著作权归作者所有,禁止商业用途转载。然后再进行检查:

本文版权归作者所有,未经授权不得转载。【转载请注明来源】转载请注明出处:www.tangshuang.net
|-types
|  |-person
|  |-book
|  |  |-book.js
|  |-benifit
|-controllers
|  |-return.js
// book.js
import { Dict } from 'hello-type'

export const BookType = Dict({
  name: String,
  author: String,
})
// return.js
import HelloType from 'hello-type'
import { BookType } from '../types/book/book.js

export default class ReturnController {
  sell(book) {
    HelloType.expect(BookType).typeof(book)

    // 具体的业务逻辑代码
  }
}

在真正写代码的时候,数据检查不仅仅限于某【转载请注明来源】【转载请注明来源】个函数的输入处,也可以在函数结尾retu【本文首发于唐霜的博客】未经授权,禁止复制转载。rn之前对要return的数据进行检查,【原创内容,转载请注明出处】【转载请注明来源】在调用其他函数之后,对该函数执行结果进行本文版权归作者所有,未经授权不得转载。【访问 www.tangshuang.net 获取更多精彩内容】数据类型检查等等。

著作权归作者所有,禁止商业用途转载。【关注微信公众号:wwwtangshuangnet】【本文受版权保护】【作者:唐霜】

HelloType不会对原有的项目代码产【本文首发于唐霜的博客】【本文受版权保护】生任何侵入,即使是老项目,也只是通过加入未经授权,禁止复制转载。【转载请注明来源】几行代码来检查,而不会要求修改项目代码的【作者:唐霜】本文作者:唐霜,转载请注明出处。写作模式。但是即使这样,我仍然觉得在函数【本文受版权保护】【未经授权禁止转载】内,或者程序进程中进行代码注入有违和感,【转载请注明来源】【本文首发于唐霜的博客】因为HelloType.expect这句【本文受版权保护】【本文首发于唐霜的博客】代码跟我本身的业务逻辑没有半点关系,也就【本文受版权保护】本文作者:唐霜,转载请注明出处。是说,要在业务逻辑里面加入一些冗余代码,原创内容,盗版必究。【本文受版权保护】作为有洁癖的程序员,还是会有一点点不舒服【本文首发于唐霜的博客】【版权所有】唐霜 www.tangshuang.net。我想到来ES7的新特性:装饰器。

【原创内容,转载请注明出处】【原创不易,请尊重版权】著作权归作者所有,禁止商业用途转载。
// return.js
import HelloType from 'hello-type'
import { BookType } from '../types/book/book.js

export default class ReturnController {
  @HelloType.decorate.with(book => BookType.assert(book))
  sell(book) {
    // 具体的业务逻辑代码
  }
}

装饰器语法用@开头,它对正常的业务逻辑代【本文受版权保护】【原创内容,转载请注明出处】码没有侵入,只是在类的方法名前面加一句修转载请注明出处:www.tangshuang.net原创内容,盗版必究。饰语,类似注释一样,不对方法本身的代码造【访问 www.tangshuang.net 获取更多精彩内容】转载请注明出处:www.tangshuang.net成任何负担。

著作权归作者所有,禁止商业用途转载。【本文首发于唐霜的博客】【关注微信公众号:wwwtangshuangnet】【访问 www.tangshuang.net 获取更多精彩内容】

TODO原创内容,盗版必究。

著作权归作者所有,禁止商业用途转载。【版权所有】唐霜 www.tangshuang.net【本文受版权保护】

HelloType是一个运行时的数据类型【版权所有,侵权必究】【未经授权禁止转载】检查工具,运行时的缺点就是占用内存,它在原创内容,盗版必究。著作权归作者所有,禁止商业用途转载。你的程序运行时,需要花资源去进行计算。这本文作者:唐霜,转载请注明出处。【访问 www.tangshuang.net 获取更多精彩内容】也是没办法的,虽然从感觉上讲,其实并不会【转载请注明来源】未经授权,禁止复制转载。觉得慢了,毕竟纯计算还是很快的,但是作为【访问 www.tangshuang.net 获取更多精彩内容】【关注微信公众号:wwwtangshuangnet】有追求的程序员,还是希望后期对类型检查算【版权所有】唐霜 www.tangshuang.net未经授权,禁止复制转载。法进行更深入的优化,以提高性能,即使面对著作权归作者所有,禁止商业用途转载。【关注微信公众号:wwwtangshuangnet】上万条数据,也可以更高效的处理。

本文作者:唐霜,转载请注明出处。【转载请注明来源】【版权所有,侵权必究】【原创内容,转载请注明出处】【未经授权禁止转载】

另外,装饰器只能作用于类,而不能在普通声【本文首发于唐霜的博客】著作权归作者所有,禁止商业用途转载。明的函数上使用,这也是个坑,能不能有更优著作权归作者所有,禁止商业用途转载。转载请注明出处:www.tangshuang.net雅的方法,让HelloType不侵入普通原创内容,盗版必究。【原创内容,转载请注明出处】函数呢?

原创内容,盗版必究。本文作者:唐霜,转载请注明出处。著作权归作者所有,禁止商业用途转载。【原创内容,转载请注明出处】

最后就是报错信息优化,当检查到传入的值与本文作者:唐霜,转载请注明出处。【访问 www.tangshuang.net 获取更多精彩内容】类型不匹配时,要提供更准确的报错信息,帮未经授权,禁止复制转载。本文版权归作者所有,未经授权不得转载。助开发者或者用户更准确的定位具体是在哪一【未经授权禁止转载】【转载请注明来源】个数据节点上出现了问题。

【作者:唐霜】【本文首发于唐霜的博客】【访问 www.tangshuang.net 获取更多精彩内容】【访问 www.tangshuang.net 获取更多精彩内容】

2018-08-11 4733 , ,

为价值买单,打赏一杯咖啡

本文价值47.33RMB