什么是 typeself
typeself 是一个专注于 JavaScript 类型体系的开源工具库,通过使用 typeself,您可以有效地降低由于 JavaScript 动态类型系统而导致的错误率,增加代码的可读性和可维护性。
如何使用 typeself
安装
您可以通过 npm 安装 typeself:
npm install typeself
简单使用示例
接下来我们来看一个简单的使用示例:
-- -------------------- ---- ------- ------ - ----- -------- - ---- ----------- ----- ---- ------- ---- - ------ ----- - - ----- ------- ---- ------- ------ ------- -- - ----- ---- - - ----- ----- ---- --- ------ ----------------------- -- -------------------------- ------- -- ----- ----展开代码
在上述代码中,我们定义了一个名为 User
的类型,要求其拥有 name
(字符串类型)、age
(数字类型)和 email
(字符串类型)三个字段,然后通过 validate
方法对一个拥有相同字段的对象进行校验,如果通过校验,validate
方法会返回 true
。
typeself 还提供了其他一些实用的校验方式以及一些高级功能,接下来我们将更详细地讲解这些内容。
类型定义
跟上面的例子一样,typeself 的类型定义方式是通过定义一个类来实现的,这个类需要继承自 Type
。
在类型定义时,我们需要定义一个类变量 shape
,并将其设置为一个对象,这个对象的键是字段的名称,值则是该字段所能包含的类型。
typeself 内置了如下类型:
Any
:可以包含任意类型的值。String
:字符串类型。Number
:数字类型。Boolean
:布尔类型。Undefined
:undefined
类型。Null
:null
类型。NaN
:NaN
类型。Array
:数组类型,可以设置嵌套类型。Object
:对象类型,可以设置嵌套类型。Tuple
:元组类型,类似于数组,但必须有固定的长度和固定的每个元素类型。Enum
:枚举类型,限制某个字段的值只能是预定义的枚举值。Union
:联合类型,可以包含多个类型,只要其中一种类型满足即可通过校验。Intersection
:交叉类型,可以包含多个类型,需要同时满足所有类型才能通过校验。Function
:函数类型,可以指定参数类型和返回值类型。
除了以上内置类型以外,我们还可以通过继承 Type
后自定义新的类型。
校验方式
typeself 提供了两种校验方式:静态校验和动态校验。
静态校验
静态校验需要在编译期进行,即在代码运行之前,将类型检查的代码转换为原生 JavaScript 代码,因此可以在开发阶段就发现类型不匹配导致的类型错误。
静态校验使用 TypeScript
进行实现,因此在使用静态校验时需要安装 TypeScript
。
使用静态校验时,我们可以将类型定义放在类型文件中,然后在我们的代码文件中引用该类型文件。
在类定义时,我们需要给类增加一个 @Validate
的装饰器,在类实例化时就会进行校验。
示例代码如下:
-- -------------------- ---- ------- -- --------------- ------ - ---- - ---- ----------- ------ ----- ---- ------- ---- - ------ ----- - - ----- ------- ---- ------- ------ ------- -- - -- -------- ------ - -------- - ---- ----------- ------ - ---- - ---- ----------------- --------------- ----- ------- - ----------- - -- --- - -展开代码
动态校验
动态校验是在代码运行时进行的,因此不能提前发现类型错误,但可以在一定程度上确保代码的健壮性。
使用动态校验时,我们需要使用 validate
函数进行校验,这个函数接受两个参数:类型定义和需要校验的对象。
如果校验通过,函数会返回 true
,否则会抛出校验异常。
示例代码如下:
-- -------------------- ---- ------- ------ - ----- -------- - ---- ----------- ----- ---- ------- ---- - ------ ----- - - ----- ------- ---- ------- ------ ------- -- - ----- ---- - - ----- ----- ---- --- ------ ----------------------- -- -------------------------- ------- -- ----- ----展开代码
错误处理
当校验失败时,我们需要知道哪个字段出现了错误,以及出现了什么错误,typeself 提供了两个工具函数来协助我们进行错误处理:getErrorKeys
和 getErrorMsg
。
getErrorKeys
函数可以用来获取校验失败的字段名称列表,示例代码如下:
-- -------------------- ---- ------- ------ - ----- --------- ------------ - ---- ----------- ----- ---- ------- ---- - ------ ----- - - ----- ------- ---- ------- ------ ------- -- - ----- ---- - - ----- ----- ---- ----- ------ ----------------------- -- -------------- ------ ------------------------------ ------- -- ----- -------展开代码
在上述代码中,由于 age
字段的值是字符串类型,而我们定义的类型中需要它是数字类型,因此 validate
会抛出校验异常,在这种情况下,getErrorKeys
函数返回的数组中就只有 age
。
getErrorMsg
函数可以用来获取校验失败的详细错误信息,以便我们更好地定位和修复错误,示例代码如下:
-- -------------------- ---- ------- ------ - ----- --------- ----------- - ---- ----------- ----- ---- ------- ---- - ------ ----- - - ----- ------- ---- ------- ------ ------- -- - ----- ---- - - ----- ----- ---- ----- ------ ----------------------- -- --- - -------------- ------ - ----- --- - ----------------------------- ----- ---- - -- ------------ --- ---- -- - ------- --- -------- -------展开代码
在上述代码中,通过 console.log(getErrorMsg(User, user, e))
,我们可以输出详细的校验错误信息。
高级功能
接下来,我们介绍一些 typeself 的高级功能。
自定义类型
在前面的示例中,我们已经了解了如何定义内置类型,但是有时候内置类型并不能完全满足我们的需求,这时候我们可以自定义类型。
自定义类型需要继承自 Type
,并实现 validate
方法,该方法需要返回一个布尔值,表示当前校验是否通过。
示例代码如下:
-- -------------------- ---- ------- ------ - ---- - ---- ----------- ----- -------- ------- ---- - ------ --------------- - ------ ------ ----- --- -------- -- ------------ - -- - - ----- ---- ------- ---- - ------ ----- - - ----- ------- --------- --------- -- - ----- ---- - - ----- ----- --------- --------- -- -------------------------- ------- -- ----- ----展开代码
在上述代码中,我们定义了一个名为 Password
的自定义类型,要求其值必须是长度大于 6 的字符串。然后在 User
类型定义中使用该类型定义了一个 password
字段,最后通过 validate
方法校验了一个符合要求的用户对象。
函数类型
在 typeself 中,我们可以通过 Function
类型定义函数类型。
函数类型需要指定参数类型和返回值类型。
示例代码如下:
-- -------------------- ---- ------- ------ - ---- - ---- ----------- ----- -------- ------- ---- - ------ --------------- - ------ ------ ----- --- ---------- -- ------ -------------- --- --------- - - ----- ---- ------- ---- - ------ ----- - - --------- --- ---------- ----- ------- ---- ------- -- ---------- -- - ----- ---- - - --------- -------- - ----- ------- ---- ------ -- -- ------- ----------------- -- -------------------------- ------- -- ----- ----展开代码
在上述代码中,我们定义了一个函数类型 Greeting
,该函数需要接受一个对象类型为 { name: string; age: number }
的参数,返回一个字符串类型的值。
然后在 User
类型定义中使用该类型为 sayHello
参数指定了一个函数类型。函数类型的实现如下:
(params: { name: string; age: number }) => `Hello, ${params.name}!`
该函数接受一个对象参数 { name: string; age: number }
,返回一个字符串,因此满足函数类型的校验要求,最终 validate(User, user)
返回 true。
注意:在上述代码中,我们使用了 new Greeting<{ name: string; age: number }, string>()
来定义函数类型。这个语法是 TypeScript 特有的,其中 { name: string; age: number }
是函数类型的参数类型,而 string
则是返回值类型。如果您只需要定义一个无参无返回值的函数类型,可以这样定义:new Greeting<void, void>()
。
总结
本文介绍了 typeself 的基本使用方法及高级功能,通过使用 typeself,您可以有效地降低由于 JavaScript 动态类型系统而导致的错误率,增加代码的可读性和可维护性。
我们在使用 typeself 时,需要注意以下几点:
- 类型定义是通过继承自
Type
的类来实现的。 - typeself 提供了静态校验和动态校验两种方式。
- typeself 提供了内置类型,同时也支持我们自定义类型。
- 出现校验错误时,可以通过
getErrorKeys
和getErrorMsg
函数进行错误处理。 - typeself 还提供了函数类型的校验方式。
如果您还没有尝试过 typeself,现在就可以动手实践了。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/600668f9d9381d61a3540fa4