V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
pseudo
V2EX  ›  程序员

TypeScript 运行时复杂类型验证

  •  2
     
  •   pseudo · 2020-08-02 16:52:18 +08:00 · 4877 次点击
    这是一个创建于 1567 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

    直接的想法大概长这样:

    original.png

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

    guard.png

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

    complex-object.png

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

    Github Repo 链接

    25 条回复    2020-08-03 13:40:57 +08:00
    Anthony117
        1
    Anthony117  
       2020-08-02 16:56:35 +08:00 via Android   ❤️ 1
    前排 Star,API 设计得挺有趣的
    ianva
        2
    ianva  
       2020-08-02 16:59:11 +08:00
    这类的库还是挺多的,比如 https://github.com/pelotom/runtypes
    pseudo
        3
    pseudo  
    OP
       2020-08-02 17:06:32 +08:00
    @ianva #2 oh,还真没查到 😂
    dustinth
        4
    dustinth  
       2020-08-02 17:09:37 +08:00
    这个跟 TypeScript 没有关系, TypeScript 是类型抹除的, 只解决开发编译时期的问题, 不解决运行时的问题. 这样的库很多
    https://github.com/jquense/yup
    love
        5
    love  
       2020-08-02 17:13:47 +08:00
    上次看了篇文章也是类似主题:
    https://2ality.com/2020/06/validating-data-typescript.html
    duan602728596
        6
    duan602728596  
       2020-08-02 17:49:56 +08:00 via iPhone
    你需要的是 schema 来验证
    ochatokori
        7
    ochatokori  
       2020-08-02 17:54:14 +08:00 via Android
    nestjs 推荐使用 class-validator
    ysmood
        8
    ysmood  
       2020-08-02 17:54:59 +08:00
    很多,比如这个 https://github.com/portm/lier
    可以当库调 API 使用,也有在线试用 http://lier.vane.im/#/
    zhlssg
        9
    zhlssg  
       2020-08-02 18:30:24 +08:00
    学到了
    noe132
        10
    noe132  
       2020-08-02 18:42:19 +08:00
    了解一下 io-ts
    CaanDoll
        11
    CaanDoll  
       2020-08-02 21:09:00 +08:00
    class-validator + 1
    jiangzhuo
        12
    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
        13
    optional  
       2020-08-02 21:15:29 +08:00 via iPhone
    Json schema
    ChanKc
        14
    ChanKc  
       2020-08-02 23:14:27 +08:00 via Android
    噢,运行时校验
    这个和 typescript 没什么关系吧
    zrp1994
        15
    zrp1994  
       2020-08-03 02:57:02 +08:00 via Android
    楼主你这个很像 https://hapi.dev/module/joi/
    yyfearth
        16
    yyfearth  
       2020-08-03 06:17:59 +08:00 via iPhone
    @pseudo 这个就没必要自己造轮子了
    有 JsonSchema 还有 Joi
    都很成熟了

    JSON schema 可以算是标准了 有很多库可以使用 而且有各种应用
    way2explore2
        17
    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
        18
    Yadomin  
       2020-08-03 08:28:30 +08:00 via Android
    interface ?
    yazoox
        19
    yazoox  
       2020-08-03 08:29:54 +08:00
    还不是很明白这个 lib 的应用场景。
    标注一下,学习学习。
    dreamerblue
        20
    dreamerblue  
       2020-08-03 10:37:57 +08:00
    既然用了 ts,那么写类型声明和校验就尽量应该避免重复工作。
    我的方式是,复杂的校验需求,用 json schema 校验,并且通过 json-schema-to-typescript 导出一份 ts interface 。
    如果是简单的校验,可以先写 interface 然后用 ts-interface-checker 生成校验函数来用。
    MrKou47
        21
    MrKou47  
       2020-08-03 11:12:46 +08:00
    ts 哪有运行时啊...ts 现在不都是跑在 js 运行时里面吗
    Yumwey
        22
    Yumwey  
       2020-08-03 11:14:20 +08:00
    这个实现的库太多了,参考:mobx-state-tree, 简称 MST
    Yumwey
        23
    Yumwey  
       2020-08-03 11:15:05 +08:00
    还有:ts 没有所谓的运行时。
    azh7138m
        24
    azh7138m  
       2020-08-03 13:38:27 +08:00
    @Anthony117
    > API 设计得挺有趣的

    prop-types 这一脉的类型校验,不都是这个风格的 API 吗


    我也觉的从类型声明上直接导出 json schema 再做校验应该会更好
    本来我就写了类型声明,为什么还要再定义一次类型校验的规则
    yaphets666
        25
    yaphets666  
       2020-08-03 13:40:57 +08:00
    运行时是 JS 没有你想的类型验证那些 哈哈哈
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2640 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 03:23 · PVG 11:23 · LAX 19:23 · JFK 22:23
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.