TypeScript是静态类型系统,在编译时做类型检查。一般而言,如果项目所用到的所有库、模块都是基于ts的,那么静态类型已经可以避免大部分编程层面的类型问题。不过,在一些场景下来,单纯静态类型是无法解决问题的,部分数据是动态传入到系统中的,主要包含场景如下:
- 第三方数据源(接口API、本地持久化存储、postMessage等)
- 第三方调用者传参
- 全局状态变更
当然,还有其他可能,总之,单纯靠静态类型检查,无法解决运行时类型问题。因此,我写了tyshemo这个工具。它可以帮助我们完成运行时的类型检查。它暴露了很多接口,其中的Ty接口,很适合在js中作为ts的补充被使用,我们来看下。
import { Ty } from 'tyshemo'
@Ty.decorate.with([Number, Number])
class Some {
constructor(a, b) {
this.x = a + b
}
@Ty.decorate.with(String)
name = 'calc'
@Ty.decorate.with([Number], Number)
plus(y) {
return this.x + y
}
}
const some = new Some(1, 3) // ok
const some2 = new Some('1', '3') // throw error
some.name = 'ooo' // ok
some.name = 123 // throw error
const z = some.plus(2) // ok
const z1 = some.plus('3') // throw error
我们可以通过 Ty.decorate.with()
作为装饰器来限定一个类上属性的值类型,方法的参数和返回值类型。
在正常的程序中,我们有的时候也需要对值进行限定,但是由于js语言的特性,我们无法对基础类型的值进行监听,不过我们可以对object进行监听。我们可以如下操作:
const o = process.env.NODE_ENV === 'production' ? {} : Ty.decorate({}).with({
name: String,
age: Number,
})
o.name = null // throw error
o.name = 'aaa' // ok
o.age = '12' // throw error
o.age = 12 // ok
通过 process.env.NODE_ENV === 'production'
来控制当前环境,如果在正式环境,就不需要这个能力,毕竟我们在测试环境已经做过充分验证了。
要对来自API的数据进行检查,我们可以这样操作。
function getData(url) {
return fetch(url).then(res => res()).then((data) => {
if (process.env.NODE_ENV !== 'production') {
Ty.expect(data).to.be({
name: String,
age: Number,
})
}
return data
})
}
Ty
这个接口可以快速对数据进行结构化检查。tyshemo还有很多其他方面的能力,可以在它的文档中了解更多。如果你觉得这个工具还不错,给个star吧。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。