最近我一直在嘗試為用 JS 撰寫的庫創建一個型別庫。當我宣告所有命名空間、類和介面時,一些類開始給我一個錯誤TS2417。我檢查了無效覆寫方法或屬性是否有任何問題,但我找不到任何東西。一段時間后,我發現有問題的類與命名空間之一具有相同的名稱(例如 classA.B和 namespace A.B)。但這并沒有造成任何麻煩。問題在于(有問題的類的)父類具有與有問題的類完全相同的命名空間,并且該命名空間和有問題的類的命名空間具有類,該類的名稱完全相同,但具有不同的界面(我很難描述這個問題,所以我在這里模擬)。
那么問題來了,是什么導致了這個問題?
在這個例子中,有問題的類是A.C,但由于類A.C.X和 的建構式不兼容,它有問題A.B.X。
declare namespace A {
class B {
}
namespace B {
class X {
}
}
class C extends A.B {
}
namespace C {
class X {
constructor(x: number)
}
}
}
uj5u.com熱心網友回復:
(在下面我將省去命名空間A)
除了構造簽名之外,statica 一側的class可替換性檢查方式與實體一側相同;所以如果你有class X { static prop: string = "" },那么你就不能有class Y extends X { static prop: number = 2}。當您說class Y extends X您宣告除其他事項外,Y.prop可分配給X.prop. 有關更多資訊,請參閱microsoft/TypeScript#4628。不是每個人都喜歡這種約束,但它就在那里。
這意味著以下內容應該沒有錯誤:
const X: typeof B.X = C.X; // should be okay
new X(); // should be okay
但是類的具體實作很容易導致運行時錯誤:
class B {
static X = class { }
}
class C extends B {
static X = class {
constructor(x: number) {
x.toFixed();
}
}
}
這C.X是一個需要number輸入的類建構式。但是B.X是一個根本不需要任何輸入的類建構式。如果您將前者視為后者,那么在運行時您將在 上呼叫該toFixed()方法undefined。哎呀。
這就是為什么會class C extends B產生編譯器錯誤;保護您免受類的靜態方面引起的可替代性問題。
Playground 鏈接到代碼
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/399045.html
標籤:javascript 打字稿 哎呀 类型
上一篇:如何使一個班級只對另一個班級公開
