将两种类型关联在一起 [英] Associating two types together
问题描述
我有一些代码 此处 实现了命令模式.
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
参数中获取 commandType
的 type,但无法获取对类对象.
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屋!