对模糊的标题表示歉意,但我不知道该如何简洁地表达这个问题!
我正在尝试实现一个类:
class Stream<Template<T,K,I>>
我知道这在语法上是不正确的。到目前为止,我有...
class Stream<T extends object, K, I extends string> {
constructor(ledger: Ledger, template: Template<T, K, I>) {
this.ledger = ledger;
this.stream = ledger.streamQuery(template);
}
private ledger: Ledger;
private stream: DamlStream<T, K, I, readonly CreateEvent<T, K, I>[]>;
...
我想做的是制作一个通用流,这样就可以将流定义为:
stream: Stream<Record>
其中Record
是Template<T,K,I>
。
我不想将类定义为Stream<T,K,I>
,因为T
的{{1}} K
和I
看起来很讨厌,生成的哈希字符串。这看起来很丑。
TLDR:
我希望能够将流定义为Record
,而不是stream: Stream<Record>
请告知您是否有话要说!
欢呼
编辑:(更多说明)
我想用如下构造函数实例化Stream类:stream: Stream<RecordT, RecordK, RecordI>
。这里的stream = new Stream(ledger, StorageRecord)
是从后端生成的类型,类型为StorageRecord
,其中Template<T,K,I>
,K
和T
有时名称很丑。
问题是当我想将I
类成员定义为Stream
时。
例如,我只想输入stream: Stream<...>
。
我无法将Stream<StorageRecord>
定义为Stream
,因为class Stream<T>
需要一个ledger.streamQuery
作为参数。
我无法将Template
定义为Stream
,因为class Stream<T extends Template>
本身是通用的。
我需要跟踪Template
,T
和K
,因为在班上也需要它们。
答案 0 :(得分:1)
您可以使用条件infer
语法来解决此问题,第一个泛型应以最通用的方式扩展Template
,然后可以使用其他泛型来推断数据,以便您可以稍后在课堂上使用。
class Stream<Templ extends Template<any,any,any>,
T extends object=(Templ extends Template<infer A,any,any> ? A : never),
K extends any =(Templ extends Template<any,infer A,any> ? A : never),
I extends string=(Templ extends Template<any,any,infer A> ? A : never)
> {
constructor(ledger: Ledger, template: Templ) {
this.ledger = ledger;
this.stream = ledger.streamQuery(template);
}
private ledger: Ledger;
private stream: DamlStream<T, K, I, readonly CreateEvent<T, K, I>[]>;
}
这样Stream< StorageRecord>
应该可以正确推断内部参数。请注意,Stream<StorageRecord, {}, 0, "hi">
从技术上讲也是有效的,并且可能会破坏某些内容,因此要获得更严格的代码,您将必须执行以下操作:
type _inferT<Templ extends Template<any,any,any>> = Templ extends Template<infer A,any,any> ? A : never
type _inferK<Templ extends Template<any,any,any>> =(Templ extends Template<any,infer A,any> ? A : never)
type _inferI<Templ extends Template<any,any,any>> = (Templ extends Template<any,any,infer A> ? A : never)
class Stream<Templ extends Template<any,any,any>> {
constructor(ledger: Ledger, template: Templ) {
this.ledger = ledger;
this.stream = ledger.streamQuery(template);
}
private ledger: Ledger;
private stream: DamlStream<_inferT<Templ>, _inferK<Templ>, _inferI<Templ>, readonly CreateEvent<_inferT<Templ>, _inferK<Templ>, _inferI<Templ>>[]>;
}
但这真的很快就很烦人,这就是为什么我建议先将速记放在类泛型中,它为您提供对正确类型的更快引用。