我遇到一个问题,该问题是基于传入的类型来定义泛型。
我有一段代码“激活”一个类,我无法从类型参数中获取类型信息,所以我传入了类对象(而不是实例)。但是,这打破了类型推断。
这是我要执行的操作的简化示例:
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] 删除。
我来说两句