繁体   English   中英

从类型实例化通用对象

[英]Instantiate generic object from type of

我发现以下代码使用参数实例化了一个新对象T:

create<T>(type: { new(p: any): T }, val: any): T {
    return new type(val);
  }

我的目标是拥有一个可以继承以初始化数组属性的基类:

export class Base {
  create<T>(type: { new(p: any): T }, val: any): T {
    return new type(val);
  }

  init<T>(propertyArray: T[], input: any): void {
    if (propertyArray == null) {
      propertyArray = [];
      for (let i in input) {
        let tmpObj = this.create(T, i);
        propertyArray.push(tmpObj);
      }
    }
  }
}

class A extends Base {

  private _prop: B[];

  get prop() {
    return this._prop;
  }
  set prop(value: any) {
    this.init(this._prop, value);
  }

  constructor(obj: any) {
    super(obj);
    this.prop = obj && obj.item || null;
  }
}

但是在此示例中, let tmpObj = this.create(T, i); 我收到此错误:

“ T”仅指类型,在此被用作值。

我该如何纠正此问题?

谢谢

我不确定其余代码的工作方式,但是您必须传入类型的构造函数才能构造该类型的实例。


让我们检查一下create()函数的签名:

declare function create<T>(type: { new(p: any): T }, val: any): T;

这是一个通用函数,适用于调用者想要的任何类型 T (不幸地命名) type参数是您使用new调用的构造函数对象,它返回类型T的值。 它是在运行时存在的对象 ,而不是仅在设计/编译时存在的类型

对类构造函数对象使用相同的名称以及该类的实例的类型是一种令人困惑但有用的做法:

class Foo {};

这将创建一个在运行时存在的名为Foo的类构造函数对象, 以及一个在设计时存在的名为Foo的实例类型:

const foo: Foo = new Foo();

第一个Foo是类型,第二个Foo是类构造函数。 这被翻译成如下内容:

var foo = new Foo();

注意,名为Foo的类型已完全消失,因为它仅在设计时存在。 关键是:即使您经常有与类型同名的构造函数对象,它们也不能互换。 泛型类型参数是类型,而不是构造函数对象。


好的,现在让我们看看您要传递给create()

this.create(T, i)

嗯,什么T 它是通用init()方法的类型参数。 因此,它只是设计时类型的名称,而不是运行时对象的名称。 这永远都行不通。 相反,如上所述,您需要传入{ new(p: any): T }类型的构造函数对象。 但是您没有其中之一,除非您将其添加到init()的参数列表中:

init<T>(ctor: { new(p: any): T }, propertyArray: T[], input: any): void {
  // ...
  this.create(ctor, i);
  // ...
}

现在它将编译,尽管您必须在prop设置器中传入B的构造函数。 不是我知道B是什么,或者您是否有构造函数。 并不是我知道为什么init()方法仅在propertyArray参数为null时才执行某些操作,以便prop设置器只能工作一次。 并不是我知道为什么您要枚举input键并将它们用作B任何构造函数的参数。 而且...嗯,我显然对其余的代码感到困惑。 只需说您需要传递T而不是T的构造函数就可以继续。

希望能有所帮助; 祝好运。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM