带有通用参数的 TypeScript InstanceType

Pat*_*nka 5 generics typescript

我正在构建一个库,它允许消费者为它提供一个构造函数/类,它的一个实例将形成其公共成员之一。

对于一个简单的非泛型类,这很好用,我们可以在库实例的公共接口上获得准确推断的智能感知和类型安全:

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
Run Code Online (Sandbox Code Playgroud)

现在考虑这样一个场景,ConsumerProvidedClass它本身有一个通用参数,用于定义其行为的某些方面。这对问题并不重要,但实际用例是 RxJSSubject或observable 的吞吐量类型BehaviorSubject在哪里TThroughput。因此,例如:

class ConsumerProvidedClass<TThroughput> { ... }
Run Code Online (Sandbox Code Playgroud)

该库现在已扩展为允许使用者提供一个“初始值”类型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<{}>
Run Code Online (Sandbox Code Playgroud)

问题是属性上的智能感知.foo正确推断ConsumerProvidedClass不知道其通用吞吐量类型,并回退到<{}>.

我想看到的是:

library.foo // type: ConsumerProvidedClass<ConsumerProvidedModel>
Run Code Online (Sandbox Code Playgroud)

但这将依赖于能够提供TModeltoInstanceType<TNewable>作为通用参数。我无法找到有关如何执行此操作的任何信息,或者是否确实有可能。理想情况下,我想做这样的事情:

public foo: (InstanceType<TNewable>)<TModel>;
Run Code Online (Sandbox Code Playgroud)

但不幸的是,这不是有效的 TypeScript。

当然,我可以让消费者在实例化库时显式传递所有泛型类型,但我更希望在可能的情况下推断一切以获得更好的开发人员体验。

任何见解都非常感谢。也许有另一种方法可以解决我所缺少的问题。