具有类参数的泛型类型推断 [英] Generic Type Inference with Class Argument

查看:118
本文介绍了具有类参数的泛型类型推断的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



我有一段代码witch激活了一个代码类,我不能从类型参数获取类型信息,所以我传递类对象(不是实例)。但是这打破了类型推断。



以下是我想要做的一个简化示例:

  interface IActivatable {
id:number;
名称:string;
}

Class ClassA实现了IActivatable {
public id:number;
public name:string;
public address:string;
}
$ b $ class ClassB implements IActivatable {
public id:number;
public name:string;
公共年龄:数字;
}

函数激活器< T extends IActivatable>(type:T):T {
//做一些东西来返回T的新实例
}

var classA:ClassA = activator(ClassA);

到目前为止,我唯一能够提出的解决方案是改变键入参数到任意并手动设置泛型类型(如下所示)。然而,这似乎很长时间了,是否有另一种方法来实现这一点。

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

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

感谢您提供任何帮助。

解决方案

TypeScript中的类型信息在编译期间全部被擦除,所以不能直接使用任何泛型类型,例如在运行时。



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



你可以通过名称作为字符串来创建类。是;这涉及挥动你的魔术棒。您还需要注意工具链中可能影响名称的任何内容,例如任何会缩小名称的缩小器(导致您的魔法字符串不同步):

  class InstanceLoader< T> {
构造函数(private context:Object){

}

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

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& amp ;& results.length> 1)?results [1]:;
}
}

class示例{
}

class AnotherClass extends示例{
}

var x = new示例();
var y = new AnotherClass();

alert (Describer.getName(x)); //示例
alert(Describer.getName(y)); // AnotherClass

只有在您想要生成an其他类型,因为你可以获取类型名称,然后使用该对象创建东西来获得另一个类型。


I'm having an issue which defining a generic type based on a type I've passed in.

I have a piece of code witch "activates" a class, I can’t get the type information from the type parameter so I am passing in class object (not an instance). However this breaks the Type inference.

Here is a simplified example of what I'm trying to do:

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);

So far the only solution I’ve been able to come up with is to change the type of the type argument to any and manually set the generic type also (as shown below). However this seems long winded, is there another way to achieve this.

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

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

Thanks for any help you can give.

解决方案

The type information in TypeScript is all erased during compilation, so you can't directly use any of the generic types, for example, at runtime.

So here is what you can do...

You can create classes by name by passing the name as a string. Yes; this involves waving your magic-string-wand. You also need to be aware of anything in your toolchain that may affect the names, for example any minifier that will crush the names (resulting in your magic string being out of sync):

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');

You can also get type names from instances at runtime, which I have shown in example format below taken from Obtaining TypeScript Class Names at Runtime:

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

This would only be relevant if you wanted to generate "another of the same kind" as you could grab the type name and then use the object create stuff to get another.

这篇关于具有类参数的泛型类型推断的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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