具有类参数的泛型类型推断

安东尼·琼斯

我遇到一个问题,该问题是基于传入的类型来定义泛型。

我有一段代码“激活”一个类,我无法从类型参数中获取类型信息,所以我传入了类对象(而不是实例)。但是,这打破了类型推断。

这是我要执行的操作的简化示例:

interface IActivatable {
    id: number;
    name:string;
}

class ClassA implements IActivatable {
    public id: number;
    public name: string;
    public address:string;
}

class ClassB implements IActivatable {
    public id: number;
    public name: string;
    public age: number;
}

function activator<T extends IActivatable>(type:T): T {
    // do stuff to return new instance of T.
}

var classA:ClassA = activator(ClassA);

到目前为止,我唯一能想到的解决方案是将type参数的类型更改为any并手动设置通用类型(如下所示)。但是,这似乎long之以鼻,还有另一种方法可以实现这一目标。

function activator<T extends IActivatable>(type:any): T {
    // do stuff to return new instance of T.
}

var classA:ClassA = activator<ClassA>(ClassA);

谢谢你提供的所有帮助。

芬顿

TypeScript中的类型信息在编译期间会全部删除,因此您不能直接使用任何通用类型,例如在运行时。

所以这就是你可以做的...

您可以通过将名称作为字符串传递来按名称创建类。是; 这涉及挥舞你的魔术弦。您还需要注意工具链中可能影响名称的所有内容,例如,任何粉碎器都会压碎名称(导致魔术字符串不同步):

class InstanceLoader<T> {
    constructor(private context: Object) {

    }

    getInstance(name: string, ...args: any[]) : T {
        var instance = Object.create(this.context[name].prototype);
        instance.constructor.apply(instance, args);
        return <T> instance;
    }
}

var loader = new InstanceLoader<IActivatable>(window);

var example = loader.getInstance('ClassA');

您还可以在运行时从实例中获取类型名称,我以下面的示例格式显示了该格式,该格式取自在运行时获取TypeScript类名称

class Describer {
    static getName(inputClass) { 
        var funcNameRegex = /function (.{1,})\(/;
        var results = (funcNameRegex).exec((<any> inputClass).constructor.toString());
        return (results && results.length > 1) ? results[1] : "";
    }
}

class Example {
}

class AnotherClass extends Example {
}

var x = new Example();
var y = new AnotherClass();

alert(Describer.getName(x)); // Example
alert(Describer.getName(y)); // AnotherClass

仅当您想生成“相同类型的另一个”(可以获取类型名称,然后使用对象创建的东西来获取另一个)时,这才有意义。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章