【问题标题】:Dynamically access const object literal in TypeScript在 TypeScript 中动态访问 const 对象字面量
【发布时间】:2021-12-14 21:21:48
【问题描述】:

我正在使用一个生成 TypeScript 代码的 TypeScript 库,称为 ts-proto

生成的代码如下所示:

    //BasicMessage.ts

    export interface BasicMessage {
      id: Long;
      name: string;
    }

    export const BasicMessage = {
     encode(message: BasicMessage) : Writer {
        ...
     }

     fromJSON(object: any): BasicMessage {
        ...
     }
   }

   // BasicMessagePlus.ts
  
   export interface BasicMessagePlus {
      id: Long;
      name: string;
      email: string;
   }

   export const BasicMessagePlus = {
     encode(message: BasicMessagePlus) : Writer {
        ...
     }

     fromJSON(object: any): BasicMessagePlus {
        ...
     }
   }

由于生成了此代码,我无法更改它。我需要做的是创建一个接受类型名称和对象并对其进行编码的方法,如下所示:

   function encode(typeName: string, object: any): Writer {
      import(`/path/to/${typeName}`);
      return <typeName>.encode(<typeName>.fromJSON(object));
   }

   let writer1 = encode("BasicMessage", { id: 1, name: "Fake" });
   let writer2 = encode("BasicMessagePlus", { id: 1, name: "Fake", email: "fake@fake.com" });

我已经尝试过使用 eval 和 globalThis 的所有类型的技巧,但我就是找不到让我做我想做的事情的组合。感谢您的帮助!

【问题讨论】:

    标签: typescript types eval


    【解决方案1】:

    像这样的动态导入对于打字稿来说几乎是不可能的。如果这个函数通过"ThisDoesNotExist"怎么办?

    因此,您必须将所有以这种方式生成的可用项目导入一个可用于查找它们的对象中。

    import { BasicMessage } from './path/to/BasicMessage'
    import { BasicMessagePlus } from './path/to/BasicMessagePlus'
    const encodables = { BasicMessage, BasicMessagePlus }
    

    现在您可以将 typeName 限制为 keyof 该对象,一切正常:

    function encode(
      typeName: keyof typeof encodables,
      data: any
    ): string {
      const encoder = encodables[typeName]
      return encoder.encode(encoder.fromJSON(data))
    }
    

    第三行是满口的。基本上,它获取所选编码器的编码方法的参数类型。

    Playground


    注意这里的dataany 类型,主要是因为这就是你的fromJSON 方法的类型。如果您想根据选择的编码器强制将某种类型作为第二个参数,那么这会变得更加复杂。

    【讨论】:

      猜你喜欢
      • 2017-08-10
      • 2020-10-07
      • 2016-07-28
      • 2018-11-03
      • 2021-02-27
      • 1970-01-01
      • 1970-01-01
      • 2015-12-20
      • 2017-12-08
      相关资源
      最近更新 更多