[英]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
我遇到了類似的要求,最后使它以以下方式工作,嚴格不需要交集(您可以定義專用類型進行類型檢查),希望它有所幫助。
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.