将两种类型关联在一起 [英] Associating two types together

查看:20
本文介绍了将两种类型关联在一起的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一些代码 此处 实现了命令模式.

I have some code here which implements the Command pattern.

type Type<T> = Function & { prototype: T }

export class CommandBus<Context, Command> {
  private handlers = new Map<Function, Function>()
  private defaultHandler: Handler<Context, Command> = (_, command) => {
    throw new Error(`No handler registered for commands of type ${command.constructor.name}`)
  }

  constructor(readonly target: Context) {}

  handle<HandledCommand extends Command, Result>(
    commandType: Type<HandledCommand>,
    handler: Handler<Context, HandledCommand, Result>,
  ) {
    this.handlers.set(commandType, handler)
    return this
  }

  do(command: Command) {
    const handler = this.handlers.get(command.constructor) || this.defaultHandler
    return handler(this.target, command)
  }
}

export interface Handler<Context, HandledCommand, Result = void> {
  (target: Context, command: HandledCommand): Result
}

对它的测试是 这里 和其他一些使用它的例子是 这里这里.

The tests for it are here and some other examples of it being used are here and here.

我对打字稿很陌生,我无法弄清楚如何建模命令(在这个 CQRS 模式的实现中,基本上只是一条消息)和预期之间的关联结果类型.

I'm pretty new to typescript, and the thing I can't figure out is how to model the association between a Command (which in this CQRS-ish implementation of the pattern, is basically just a message) and the expected result type.

目前,我们必须指定返回类型,因为我们调用处理程序函数 但我觉得这可以被烘焙到命令的类型中,并从那里暗示来自处理程序的返回类型).

At the moment, we're having to specify the return type as we call the handler function but I feel like this could be baked into the type of the Command, and from there imply a return-type from the Handler).

我想我可能需要使用元组类型,这样一个命令不仅被定义为 GetRefs 或其他什么,而是作为 [GetRefs, Promise.我不确定在哪里或如何执行此操作.

I think I maybe need to use a tuple type, such that a command is defined not just as GetRefs or whatever, but as [GetRefs, Promise<Ref[]>. I'm not sure where or how to do this.

推荐答案

据我所知,您正在寻找一种方法来更改 handle

As I understand it, you're looking for a way to change handle from

handle<HandledCommand extends Command, Result>(
    commandType: Type<HandledCommand>,
    handler: HandlesCommands<Context, HandledCommand, Result>,
  ): CommandBus<Context, Command> {
    this.handlers.set(commandType, handler)
    return this
  }

handle<HandledCommand extends Command, Result>(
    handler: HandlesCommands<Context, HandledCommand, Result>,
  ): CommandBus<Context, Command> {
    const commandType: Type<HandledCommand> = magic(handler)
    this.handlers.set(commandType, handler)
    return this
  }

是吗?

如果是这样,简短的回答是不".您需要引用 commandType 的类对象,以便在运行时用作处理程序的键.您可以从 handler 参数中获取 commandTypetype,但无法获取对类对象.

If so, the short answer is "no". You need a reference to the class object for commandType to use at runtime as a key for the handlers. You can get the type of commandType from the handler argument, but you can't get a reference to the class object.

区别在于类型声明空间变量声明空间——更多关于TypeScript 深入探讨:声明空间.

The distinction is between type declaration space and variable declaration space -- more on that in TypeScript Deep Dive: Declaration Spaces.

由于您无法从类型中获取类对象,因此对您的问题的任何回答都将相当于重新安排代码,以便以其他方式将类对象作为参数传入——但它仍然需要以某种方式传递给每个对 handle 的调用.

Since you can't get the class object from a type, any answer to your question will amount to re-arranging the code so the class object is passed in as a parameter in some other way -- but it will still need to be passed in to each call to handle somehow.

这篇关于将两种类型关联在一起的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆