TypeScript 运行时复杂类型验证

2020-08-02 16:52:18 +08:00
 pseudo

最近在用 TypeScript 开发后端服务,遇到了一个棘手的问题:如何在运行时快速地验证请求中的数据并推导为所需的强类型变量?

直接的想法大概长这样:

不出意外,这样下去很快代码会出现很多类似判断并变得十分臃肿。经过一番搜索,发现虽然 TypeScript 允许自定义 type guard,但并不提供原生的运行时验证库(也确实不应该在 TypeScript 层面解决这个问题)。于是自己动手开发了一个工具库 power-guard ,它的语法是这样:

它提供多种内置函数,基本覆盖大部分常用的基础 /复杂类型的验证:object,array,enum,number,string,boolean,同时你可以进行自由定制来验证更为复杂的对象:

再也不用担心用户乱输入了。:-)

Github Repo 链接

4912 次点击
所在节点    程序员
25 条回复
Anthony117
2020-08-02 16:56:35 +08:00
前排 Star,API 设计得挺有趣的
ianva
2020-08-02 16:59:11 +08:00
这类的库还是挺多的,比如 https://github.com/pelotom/runtypes
pseudo
2020-08-02 17:06:32 +08:00
@ianva #2 oh,还真没查到 😂
dustinth
2020-08-02 17:09:37 +08:00
这个跟 TypeScript 没有关系, TypeScript 是类型抹除的, 只解决开发编译时期的问题, 不解决运行时的问题. 这样的库很多
https://github.com/jquense/yup
love
2020-08-02 17:13:47 +08:00
上次看了篇文章也是类似主题:
https://2ality.com/2020/06/validating-data-typescript.html
duan602728596
2020-08-02 17:49:56 +08:00
你需要的是 schema 来验证
ochatokori
2020-08-02 17:54:14 +08:00
nestjs 推荐使用 class-validator
ysmood
2020-08-02 17:54:59 +08:00
很多,比如这个 https://github.com/portm/lier
可以当库调 API 使用,也有在线试用 http://lier.vane.im/#/
zhlssg
2020-08-02 18:30:24 +08:00
学到了
noe132
2020-08-02 18:42:19 +08:00
了解一下 io-ts
CaanDoll
2020-08-02 21:09:00 +08:00
class-validator + 1
jiangzhuo
2020-08-02 21:12:51 +08:00
现在用的方法是写 typescript 类型
然后生成 json schema
用 schema 验证数据的 json
==================
xz 用的 ff 是写 ts 类型
然后 sc J$0N 4 个 ma
用 4 个 ma 炎症 sj 的 J$0N
optional
2020-08-02 21:15:29 +08:00
Json schema
ChanKc
2020-08-02 23:14:27 +08:00
噢,运行时校验
这个和 typescript 没什么关系吧
zrp1994
2020-08-03 02:57:02 +08:00
楼主你这个很像 https://hapi.dev/module/joi/
yyfearth
2020-08-03 06:17:59 +08:00
@pseudo 这个就没必要自己造轮子了
有 JsonSchema 还有 Joi
都很成熟了

JSON schema 可以算是标准了 有很多库可以使用 而且有各种应用
way2explore2
2020-08-03 07:08:36 +08:00
重复造轮子!!! :(

```
const Joi = require('@hapi/joi');

const schema = Joi.object({
username: Joi.string()
.alphanum()
.min(3)
.max(30)
.required(),

password: Joi.string()
.pattern(new RegExp('^[a-zA-Z0-9]{3,30}$')),

repeat_password: Joi.ref('password'),

access_token: [
Joi.string(),
Joi.number()
],

birth_year: Joi.number()
.integer()
.min(1900)
.max(2013),

email: Joi.string()
.email({ minDomainSegments: 2, tlds: { allow: ['com', 'net'] } })
})
.with('username', 'birth_year')
.xor('password', 'access_token')
.with('password', 'repeat_password');

```

有那么多现成 validation 库,都能满足需求 😕
Yadomin
2020-08-03 08:28:30 +08:00
interface ?
yazoox
2020-08-03 08:29:54 +08:00
还不是很明白这个 lib 的应用场景。
标注一下,学习学习。
dreamerblue
2020-08-03 10:37:57 +08:00
既然用了 ts,那么写类型声明和校验就尽量应该避免重复工作。
我的方式是,复杂的校验需求,用 json schema 校验,并且通过 json-schema-to-typescript 导出一份 ts interface 。
如果是简单的校验,可以先写 interface 然后用 ts-interface-checker 生成校验函数来用。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/695040

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX