Ant*_*nes 13 generics typescript
我遇到了一个基于我传入的类型定义泛型类型的问题.
我有一段代码巫婆"激活"一个类,我无法从类型参数中获取类型信息,所以我在类对象(而不是实例)中传递.然而,这打破了类型推断.
这是我正在尝试做的简化示例:
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并手动设置泛型类型(如下所示).然而,这似乎很长,有另一种方法来实现这一目标.
function activator<T extends IActivatable>(type:any): T {
    // do stuff to return new instance of T.
}
var classA:ClassA = activator<ClassA>(ClassA);
谢谢你提供的所有帮助.
blo*_*ish 41
根据语言规范,您需要通过它的构造函数来引用类类型.所以不使用type:T,请使用type: { new(): T;}如下:
function activator<T extends IActivatable>(type: { new(): T ;} ): T {
    // do stuff to return new instance of T.
    return new type();
}
var classA: ClassA = activator(ClassA);
这就是Typescript团队推荐的方法:
基本上与blorkfish的答案相同,但是提取到界面.
interface IConstructor<T> {
    new (...args: any[]): T;
    // Or enforce default constructor
    // new (): T;
}
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: IConstructor<T>): T {
    return new type();
}
const classA = activator(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
这只有在您想要生成"另一种相同类型"时才能获得,因为您可以获取类型名称,然后使用对象创建内容来获取另一种类型.
| 归档时间: | 
 | 
| 查看次数: | 12219 次 | 
| 最近记录: |