Typescript:如何在依赖项中返回正确的类和泛型 [英] Typescript: how to return the proper class and generic type in a dependency

查看:158
本文介绍了Typescript:如何在依赖项中返回正确的类和泛型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试找到一种将对象注入另一个对象的方法(依赖项注入),其中容器对象可以返回正确注入的对象类型 ,和无需将类型明确传递给函数(类型推断)。

为确保注入的对象具有公共接口和默认行为,它们将是

I'm trying to find a way to inject an object into another object (dependency injection), in which the container object can return the proper injected object type, and no need to explicitly pass types to the function (type inference).
To make sure the injected objects have a common interface and a default behavior, they'd be instances of an Abstract class.

鉴于我在某个特定的位置需要这种行为,我想避免使用依赖注入框架来实现。

Given that I'd need such a behavior at some ponctual place, I would like to avoid using a dependency injection framework to do so.


在我看来,我需要设置对象实例化的泛型类型,因为此后无法重新定义泛型参数。因此,我需要使用工厂 new()接口)






这里是一个例子。 在Typescript Playground中进行测试。为简单起见,我正在寻找 createMyClass2 返回类型为 ArrayClass< string> 的对象。

可以认为 ArrayClass ArrayClassAbstract 是在不同的 NPM 模块中定义的某种插件。


Here is an example. Test it in Typescript Playground. To make things simple, I'm looking for createMyClass2 to return an object typed ArrayClass<string>, without specifying the type explicitly when calling it (type inference).
It may be considered that ArrayClass and ArrayClassAbstract are some kind of plugins defined in different NPM modules for example.

class ArrayClassAbstract<MYTYPE> {
    public arr: Array<MYTYPE> = []
    constructor(element: MYTYPE) {
        this.arr.push(element);
    }
}

class ArrayClass<MYTYPE> extends ArrayClassAbstract<MYTYPE> {
    test() { 
        return this.arr;
    }
}

class SomeOtherArrayClass<MYTYPE> extends ArrayClassAbstract<MYTYPE> {
    test() { 
        return this.arr + "something different";
    }
}

function createMyClass<MYTYPE>
    (className: { new <MYTYPE>(element: MYTYPE): ArrayClassAbstract<MYTYPE> }, element: MYTYPE) { 
    return new className<MYTYPE>(element);
}

let a = createMyClass(ArrayClass, "hop!");   // type: {ArrayClassAbstract<string>}
a.test();                                    // Doesn't work... "test" doesn't exist in ArrayClassAbstract

良好的通用类型,错误的类类型...

Good generic type, wrong class type...

function createMyClass2<T extends ArrayClassAbstract<string>>
    (className: { new (element: string): T }, element: string) { 
    return new className(element);
}

let b = createMyClass2(ArrayClass, "hop!");  // type: {ArrayClass<any>}
b.test();                                    // Works but array elements typed as "any"

好的类类型,错误的泛型类型。
我不知道我声明工厂的方式是否有问题,或者我是否是Typescript限制的受害者...

Good class type, wrong generic type. I don't know if there's something wrong in my way to declare the factory, or if I'm victim of Typescript limitations...

任何想法?

推荐答案

如何使用重载?

function createMyClass2<MYTYPE>(type: typeof ArrayClass, element: MYTYPE): ArrayClass<MYTYPE>;
function createMyClass2<MYTYPE>(type: typeof SomeOtherArrayClass, element: MYTYPE): SomeOtherArrayClass<MYTYPE>;
function createMyClass2(className, element) {
    return new className(element);
}

let b = createMyClass2(ArrayClass, "hop!");  // type: {ArrayClass<string>}
b.test();
let c = createMyClass2(ArrayClass, 123);  // type: {ArrayClass<number>}
c.test();
let d = createMyClass2(SomeOtherArrayClass, "hop!");  // type: {SomeOtherArrayClass<string>}
d.test();

这篇关于Typescript:如何在依赖项中返回正确的类和泛型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆