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

TS 里两个自定义数据结构类型转换移除多余字段

  •  
  •   zed1018 · 2022-08-17 10:52:21 +08:00 · 1490 次点击
    这是一个创建于 806 天前的主题,其中的信息可能已经有所发展或是发生改变。

    两个 interface A B , B 是 extends A 多两个字段,想在 B 转换成 A 类型时移除这两个字段,我知道 TS 实际只是编译检查,实际没有类型,b as A或者{...b} as A实际还是 B 的字段。现在是 {...b, b[a]: undefined, b[a1]: undefined} as A 这样弄,有没有什么工具或者方案能不手写多余的那两个字段的置未定义的方案,能自动的吧按照 A 的字段 pick 一遍。

    3 条回复    2022-08-19 07:02:56 +08:00
    gofishing
        1
    gofishing  
       2022-08-17 11:04:16 +08:00
    ```ts
    interface A {
    a: string
    b: string
    c: string
    }

    interface B extends Omit<A, 'a' | 'b'> {
    d: string
    e: string
    }
    ```
    zed1018
        2
    zed1018  
    OP
       2022-08-17 15:22:41 +08:00
    @gofishing 我并不是要去掉 A 的 a,b 字段。比如

    interface A {
    a: string
    b: string
    c: string
    }

    interface B extends A {
    d: string
    e: string
    }


    const b: B = {a: '1', b:'2',c:'3',d:'4',e:'5'}

    我想把 b 的类型转换成 A 的时候实际的值是这样的

    const btoa: A = {a: '1', b:'2',c:'3'}

    现在
    const btoa = b as A

    const btoa = {...b} as A

    最后 btoa 里还是 abcde 都有
    YuJianrong
        3
    YuJianrong  
       2022-08-19 07:02:56 +08:00
    TLDR 版:不行。

    加长版:
    你已经说了 interface 只是编译期存在的类型,运行时是没有类型信息的,所以不管什么工具都不可能把多余参数擦除。要擦出多余参数,这个 interface 的类型信息必须在运行时必须能拿到,这就需要别的方式辅助,一个方案是用装饰器,但这增加了不少代码量;另一个方案是用第三方工具比如 typescript-json-schema 或者 ts-json-schema-generator 在编译期把 TS 的 interface 编译成 JSON Schema ,这样在运行时你就可以读取 Schema 来过滤这个 Object 了。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1323 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 23:37 · PVG 07:37 · LAX 16:37 · JFK 19:37
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.