簡體   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