在 TypeScript 中动态访问 const 对象字面量

Posted

技术标签:

【中文标题】在 TypeScript 中动态访问 const 对象字面量【英文标题】:Dynamically access const object literal in TypeScript 【发布时间】: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 的所有类型的技巧,但我就是找不到让我做我想做的事情的组合。感谢您的帮助!

【问题讨论】:

【参考方案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 方法的类型。如果您想根据选择的编码器强制将某种类型作为第二个参数,那么这会变得更加复杂。

【讨论】:

以上是关于在 TypeScript 中动态访问 const 对象字面量的主要内容,如果未能解决你的问题,请参考以下文章

window[name] 相当于动态访问 const 和 let 声明

是否可以在 Typescript 中迭代 const 枚举?

Typescript const枚举问题

为啥我们不能在 TypeScript 类中定义一个 const 字段,为啥静态只读不起作用?

Node.js 和 Typescript,如何动态访问导入的模块

TypeScript 中 as const 是什么