我正在构建一个库,允许消费者为其提供构造函数/类,其实例将构成其公共成员之一 .
对于一个简单的非泛型类,这个工作正常,我们在库实例的公共接口上得到准确推断的intellisense和类型安全:
class MyLibrary<TNewable extends new (...args: any[]) => any> {
public foo: InstanceType<TNewable>;
constructor(ConsumerNewable: TNewable) {
this.foo = new ConsumerNewable();
}
}
class ConsumerProvidedClass {}
const library = new MyLibrary(ConsumerProvidedClass);
library.foo // type: ConsumerProvidedClass
现在考虑 ConsumerProvidedClass
本身有一个通用参数的场景,该参数定义了其行为的某些方面 . 对于这个问题并不重要,但实际的用例是RxJS Subject
或 BehaviorSubject
,其中 TThroughput
是可观察的吞吐量类型 . 所以,例如:
class ConsumerProvidedClass<TThroughput> { ... }
该库现在已扩展为允许使用者提供"initial value"类型 TModel
,它将在实例化时传递给 ConsumerProvidedClass
,并且也成为其吞吐量类型:
class MyLibrary<TNewable extends new (...args: any[]) => any, TModel> {
public foo: InstanceType<TNewable>;
constructor(ConsumerNewable: TNewable, initialValue: TModel) {
this.foo = new ConsumerNewable(initialValue);
}
}
class ConsumerProvidedClass<TThroughput> {}
class ConsumerProvidedModel {}
const library = new MyLibrary(ConsumerProvidedClass, new ConsumerProvidedModel());
library.foo // type: ConsumerProvidedClass<{}>
问题是属性 .foo
上的intellisense正确推断 ConsumerProvidedClass
但不知道它的通用吞吐量类型,并回退到 <{}>
.
我想看到的是:
library.foo // type: ConsumerProvidedClass<ConsumerProvidedModel>
但这将依赖于能够提供 TModel
到 InstanceType<TNewable>
作为通用参数 . 我无法找到有关如何执行此操作的任何信息,或者确实有可能 . 理想情况下,我想做这样的事情:
public foo: (InstanceType<TNewable>)<TModel>;
但不幸的是,这不是有效的TypeScript .
当然,我可以让消费者在实例化库时显式传递所有泛型类型,但我更希望在可能的情况下推断所有内容以获得更好的开发人员体验 .
任何见解都非常赞赏 . 也许还有另一种方法可以解决这个问题,我很想念 .