在Rails事件存储中,AggregateRoot具有DSL方法,这些方法导致具有此形状的块:
class X
extend AggregateRoot::OnDSL
class MyEvent < RailsEventStore::Event; end
on MyEvent do |event|
# Code
end
end在这个块中,可以访问类实例数据。但冰糕不知道。
有没有办法告诉Sorbet,该块将作为实例方法被注入?
我可以将字段或方法的每次使用标记为T.unsafe(),但这将从其中移除类型,并且添加强制转换会使代码难以阅读。
发布于 2022-07-11 20:41:07
您可以使用T.bind与Sorbet通信,self在特定块中具有特定类型:
class X
extend AggregateRoot::OnDSL
class MyEvent < RailsEventStore::Event; end
on MyEvent do |event|
T.bind(self, MyEvent)
# Code
end
end更广泛地说,您可以添加一个shim,它指定像这样的DSL和指定proc将绑定到的类型。 (如:T.proc.bind(TheTypeOfSelfInTheBlock).params(...).returns(...) )的类型。
在这种情况下,对于AggregateRoot::OnDSL.on来说,如果不是不可能的话,它会有点棘手,原因有两个:
on需要一个*event_klasses。您无法确定哪个事件类触发了您的块,因此您无法静态地知道传递给您的块的事件是哪个event_klasses。event_klasses的类型应该是event_klasses: T.class_of(RailsEventStore::Event)。即使它是一个奇异值,您也需要泛型系统来表示块的参数是特定的event_klasses类型(而不仅仅是任何RailsEventStore::Event)。我认为这目前是不可能的。https://stackoverflow.com/questions/72898097
复制相似问题