簡體   English   中英

打字稿:類擴展了泛型類型

[英]Typescript: Class extends a Generic Type

我知道它太通用了,但我希望創建一個類,該類將包含這樣的通用類型的所有道具和原型:

class GenericExtend<T> extends T {
    constructor(data: T) {
        // here is a workaround to make these 2 classes unique
        const proto = { ...GenericExtend.prototype };
        Object.assign(proto, Object.getPrototypeOf(data));
        Object.setPrototypeOf(this, proto);
        Object.assign(this, data);
    }

    GenericMethod() { }
}

現在,我可以實例化GenericExtend類,然后像這樣獲取兩個類的類型:

const obj = new GenericExtend<Model>(data);
obj.GenericMethod(); // ok
obj.ModelMethod(); // good!

我的解決方案之一是使用交集,如下所示:

const obj: GenericExtend & Model = new GenericExtend(data) as any;

它奏效了,但我不太喜歡。 有什么我可以做的更好的事情嗎?

打字稿不會讓你實現或擴展其他類型的T ,除非所有的鑰匙T在編譯時靜態已知。 這可以防止class GenericExtend<T> implements T {...}成為您可以編寫的東西。

相反,您必須使用交集來獲得此行為……但是如果需要,您可以將類型斷言限制在構造函數中,以便后續使用不需要它。 讓我們將GenericExtend重命名為:

class _GenericExtend<T> {
  constructor(data: T) {
    const proto = { ..._GenericExtend.prototype };
    Object.assign(proto, Object.getPrototypeOf(data));
    Object.setPrototypeOf(this, proto);
    Object.assign(this, data);
  }
  GenericMethod() { }
}

然后將GenericExtend重新定義為具有您想要的交集行為的類型和構造函數:

type GenericExtend<T> = _GenericExtend<T> & T;
const GenericExtend: new <T>(data: T) => GenericExtend<T> = _GenericExtend as any;

最后as any是我們需要的類型斷言。 現在你應該能夠得到你想要的行為:

interface Model {
  ModelMethod(): void;
}
declare const data: Model;

const obj = new GenericExtend(data);
obj.GenericMethod(); // ok
obj.ModelMethod(); // ok

Playground 鏈接到代碼

我遇到了類似的要求,最后使它以以下方式工作,嚴格不需要交集(您可以定義專用類型進行類型檢查),希望它有所幫助。

class A {
  a() {
    ...
  }
}

class B {
  b() {
    ...
  }
}

type Constructor = new (...args: any[]) => any

function genericExtend<T extends Constructor>(target: T) {
  return class GenericExtended extends target {
    constructor(...args: any[]) {
      super(...args)
    }

    genericMethod() {
      ...
    }
  }
}

const instanceOfA: GenericExtended & A = new (genericExtend(A))()
const instanceOfB = new (genericExtend(B))()

instanceOfA.a() // ok with type checking
instanceOfA.genericMethod() // ok with type checking

instanceOfB.b() // ok without type checking
instanceOfB.genericMethod() // ok without type checking

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM