我最近遇到了一個問題,我無法從其他問題中找出解決方案。所以基本上我想要實作的是:
我有很多抽象類,我必須創建更多從其他抽象類擴展的抽象類,例如:
abstract class MyAbstractClass extends Mixin(A, B | C | D)
其中 Mixin 是 ts-mixer npm 包中的一個函式,而 A 是一個不會改變的抽象類,它保持不變,但是另一個類是未知的。
我嘗試了泛型但沒有運氣,我嘗試創建一個工廠函式,但我無法回傳這樣的抽象類
return abstract class MyAbstractClass extends Mixin(A, param){}
只是一個非抽象類。
如果有人可以提供答案或指出我正確的方向,我將不勝感激
編輯:我目前正在做的是:
abstract class Button{
abstract onToggle():void
}
abstract class A{
abstract foo():void
}
abstract class B{
abstract bar():void
}
abstract class ExtendedButtonA extends Mixin(Button, A){}
abstract class ExtendedButtonB extends Mixin(Button, B){}
所以當我做最后一堂課時,我必須這樣做:
class FinalButtonA extends ExtendedButtonA{}
class FinalButtonB extends ExtendedButtonB{}
我想能夠做什么:
class FinalButton extends ExtendedButton<A>{}
或類似的東西。
uj5u.com熱心網友回復:
我的建議是這樣撰寫ExtendedButton工廠函式:
function ExtendedButton<T extends abstract new (...args: any) => InstanceType<T>>(
ctor: T
) {
return Mixin(Button, ctor);
}
這似乎適用于您的示例代碼:
abstract class A {
abstract foo(): void
}
abstract class FinalButton extends ExtendedButton(A) { }
function foo(fb: FinalButton) {
fb.foo();
fb.onToggle();
}
我這樣做的方法是首先看看當你Mixin(Button, A)直接呼叫時會發生什么:
const testA = Mixin(Button, A)
// const testA: Class<any[], Button & A, typeof Button & typeof A, false>
然后將其與通用版本進行比較,而不是A我們傳入ctor通用抽象構造簽名型別的值:
function ExtendedButton<T extends abstract new (...args: any) => object>(
ctor: T
) {
return Mixin(Button, ctor);
}
const testA2 = ExtendedButton(A);
// const testA2: Class<any[], Button & object, typeof Button & typeof A, false>
這里的區別在于第二種型別的引數Button & object不是所需的Button & A。這是為什么?似乎編譯器正在將建構式擴大到它的約束 abstract new (...args: any) => object并獲取它的實體型別,過早地擴大到object我們想要的時候A。
好吧,如果它要使用那個約束,也許我們可以使約束本身成為通用的,這樣它仍然有用。給定一個類似建構式的型別T,我們可以使用實用InstanceType<T>程式型別來表示它的實體型別。所以讓我們object改為InstanceType<T>:
function ExtendedButton<T extends abstract new (...args: any) => InstanceType<T>>(
ctor: T
) {
return Mixin(Button, ctor);
}
幸運的是編譯(有時遞回約束不編譯),現在呼叫簽名看起來像
// function ExtendedButton<T extends abstract new (...args: any) => InstanceType<T>>(
// ctor: T
// ): Class<any[], Button & InstanceType<T>, typeof Button & T, false>
其中第二個型別引數是Button & InstanceType<T>。讓我們試一試:
const testA3 = ExtendedButton(A);
// const testA3: Class<any[], Button & A, typeof Button & typeof A, false>
完美,這與我們Mixin直接呼叫得到的型別相同。
Playground 代碼鏈接
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/528373.html
下一篇:在ac宏中包裝可變引數
