如何存储“类型”并在打字稿中动态实例化它们?

问题描述 投票:0回答:1

我正在尝试完成与

C#
类似的行为。在
C#
中,我可以使用反射来动态实例化基于
Type
类的类。下面的代码展示了如何在
c#
中进行操作,相当简单:

interface IHandler
{
   void Handle();
}
var handlers = new Dictionary<string, Type>
{
  { "querydom", typeof(QueryDomHandler) },
  { "other", typeof(OtherHandler) },
};

var type = handlers["querydom"];
var instance = (IHandler)Activator.CreateInstance(type, args);
instance.Handle();

如何使用

typescript
实现同样的效果?我绘制了以下代码,但我不知道如何从类中获取“类型”(
QueryDomCommandHandler
),或者如何在不使用类名称的情况下动态实例化类(
 new QueryDomCommandHandler()
)。

let handlers = [];
handlers[CommandType.QueryDom] = QueryDomCommandHandler; //how to store the "type"?

chrome.runtime.onMessage.addListener((message: Command, sender, sendResponse) => {
    logger.debug(`${isFrame ? 'Frame' : 'Window'} '${document.location.href}' received message of type '${CommandType[message.command]}'`);
 
    const handlerType = handlers[CommandType.QueryDom];
    const handlerInstance = ????? //how to instantiate the class?
    if (message.command == CommandType.QueryDom) {
        const handler = new QueryDomCommandHandler(message as RulesCommand);
        const response = handler.handle();
        sendResponse(response);
        return true;
    }
    else if (message.command == CommandType.Highlight) {
        const handler = new HighlightCommandHandler(message as RulesCommand);
        handler.handle();
    }
});

有什么见解吗?

更新

感谢您的回答,这是我的解决方案,虽然我想使用

enum
而不是
Record
中的硬编码字符串,但无法弄清楚:

const handlers: Record<string, (new () => commands.CommandHandlerBase)> = {
    'QueryDom': QueryDomCommandHandler,
    'Highlight': HighlightCommandHandler,
    'ClearHighlight': ClearHighlightCommandHandler,
};

    const handlerType = handlers[commands.CommandType[message.command]];
    const handler = new handlerType();
    const response = await handler.handle(message);
typescript reflection instantiation
1个回答
1
投票

注意:你无法在打字稿中获取“类型”,因为该类型在运行时不存在,你得到的实际上是类的构造函数。

您首先需要在

handlers

 数组上输入某种类型才能进行推理:

let handlers: (new (...arg: any[]) => CommandHandler)[] = [];

CommandHandler

部分修改为处理程序基类的名称

获取构造函数后创建实例,只需

new

即可,
类名本身并不重要:

const handlerInstance = new handlerType() // ^? const handlerInstance: CommandHandler
    
© www.soinside.com 2019 - 2024. All rights reserved.