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

TS+Axios 能指定解析的对象吗

  •  
  •   HoseaDev · 2022-09-24 16:10:30 +08:00 · 1805 次点击
    这是一个创建于 791 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我以前是 Android 开发的后台返回的 Json:{ "id":1, "name":"age" } 我在 android 中我定义一个 Bean ,我把 id 的类型定义成 String,我解析出来我用的时候就是 String 。 我发现我在 TS+Axios 中,这是我定义的 Bean export interface CategoryData { id?: string

    name?: string

    parent?: string

    sort?: string children?: CategoryData[] }

    id 定义为 string 我得到的数据依然是 number 。 研究了好多都没有发现怎么解决这个问题, 有没有大佬指点 1.2

    16 条回复    2022-09-30 13:04:42 +08:00
    sarices
        1
    sarices  
       2022-09-24 16:16:22 +08:00
    这不是应该后端返回正确格式吗,你定义这个 interface 只是约束前端而已
    thinkershare
        2
    thinkershare  
       2022-09-24 16:17:46 +08:00
    你服务器序列化为什么,客户端就解析成什么, 这个后 TS 和 axios 都没啥关系。 你应该修改你的服务器, 让它返回: {"id":"1"} 而不是: {"id":1}
    thinkershare
        3
    thinkershare  
       2022-09-24 16:18:14 +08:00   ❤️ 2
    TS 没有 Runtime 行为。
    BeautifulSoap
        4
    BeautifulSoap  
       2022-09-24 16:22:49 +08:00 via Android
    直接 json 解析不能直接用的,JSON.parse()解析后你需要使用 class-transformer 这个库再做一次转换,把 plain object 转换成具体的 object 。class-transformer 在转换时可以通过装饰器自定义转换逻辑,这样就能达到你的目的了

    但是因为 JS 是的动态语言,光这样依旧不能保证你转换后的数据一定符合需要的结构和类型,所以你还需要配合使用 class-validator 这个库给最后的 object 做个一 validation 。

    然后你使用 class-transformer ,class-validator
    这两个库体验并不好,因为 JS 和 TS 语言本身的问题,所有内嵌类和数组之类的他没法自动识别出是什么类型,所以你还必须手动用装饰器明确标注成员类型

    是的,TS 写后端的体验就是这么朴实难用且糟糕 :)
    signalas1
        5
    signalas1  
       2022-09-24 17:28:29 +08:00
    很明显 后端返回的 1 是 "1"
    Envov
        6
    Envov  
       2022-09-24 17:28:53 +08:00
    axios.post<T> T 就是响应的类型吧,
    类似于在这样
    type userInfo={
    name:string,
    id:number,
    }
    axios.post<userInfo>
    liuw666
        7
    liuw666  
       2022-09-24 18:21:20 +08:00 via iPhone
    不能。TS 的类型不是运行时。 后端返回啥就是啥
    lisongeee
        8
    lisongeee  
       2022-09-24 18:34:44 +08:00
    你的问题使用 ts 编译器宏可以解决,定义一个宏标记函数,传入一个类型,编译的时候替换为 类型转换器
    cweijan
        9
    cweijan  
       2022-09-24 19:02:07 +08:00
    ts 只是个类型系统, 不像 Java 一样有个序列化的过程, 只能手动处理.
    eraserking
        10
    eraserking  
       2022-09-24 20:01:55 +08:00
    不能。
    TS 的类型系统只约束编译期。代码里的类型你可以随便写,但是运行时的效果以实际为准。
    wu67
        11
    wu67  
       2022-09-24 20:22:37 +08:00
    如果你要确保类型, 应该用强制类型转换...

    个人认为, ts 本质是用类型和各种约束统一团队的编码、避免一些低级错误, 并且这个作用时间是开发中 /编译完成前.
    slmakm
        12
    slmakm  
       2022-09-25 11:29:44 +08:00
    谢谢上面大佬们的回复,对 TS 的认识又加深了。不用就忘
    HoseaDev
        13
    HoseaDev  
    OP
       2022-09-25 12:42:52 +08:00
    @sarices @thinkershare @BeautifulSoap @liuw666 @cweijan @eraserking @wu67 谢谢大佬们的指点,大概明白了,Java 写惯了来写这个确实需要适应。
    darkengine
        14
    darkengine  
       2022-09-25 17:52:57 +08:00
    其实不是 TS + Axios 的问题。是因为 Android 的库例如 gson ,会帮你把后端的传回来的字段改成你想要的类型,例如文中你要的 String 类型的 id 。而 TS + Axios 不会(主动)帮你做这个事情。
    HoseaDev
        15
    HoseaDev  
    OP
       2022-09-25 22:46:20 +08:00
    @darkengine 是的。TS 只是类型约束,并不会做其他事情,axios 会使用默认的 JSON.parse() 来进行解析。如果 JS 有类似 Gson 的库能解析的时候传个泛型进去就能解决我的问题。
    jingcoco
        16
    jingcoco  
       2022-09-30 13:04:42 +08:00
    有可以实现类似需求的 js 库 。。。。。。 网上搜搜 js 数据验证器 yup
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2201 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 01:30 · PVG 09:30 · LAX 17:30 · JFK 20:30
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.