2016-11-30 95 views
0

我正在創建一個基類(這裏稱爲頂部),我想用它爲它的所有子元素創建一個藍圖。我通過在基礎上創建抽象函數來做到這一點,以便孩子們必須執行該操作才能生效。下面是一個例子抽象方法的實現不需要相同的簽名

interface ITopData { } 

abstract class top{ 

    constructor() { } 

    abstract test<T extends ITopData>(data: T): void; 

} 

interface IBottomData extends ITopData { } 

class bottom extends top { 

    constructor() { super() } 

    test<IBottomData>(data) { return } 

} 

但是,這是所需的代碼時,我這樣寫

class bad extends top { 

    constructor() { super() } 

    test(data: string) { return } 
    //these implementations also dont cause any complaints 
    //test<T extends string>(data) { return } 
    //test() { return } 

} 

我要什麼類是打字稿抱怨級「壞」犯規適當擴大級「頂」。當我寫出來,雖然我沒有從我的intellisense或我的transpiler投訴。

編輯:如果一個子類沒有任何函數的實現,我會得到錯誤,但是在使用上面顯示的任何實現時會出錯。

回答

2

有一點要記住的是,string匹配interface ITopData {} - 由於接口沒有屬性,任何對象類型都會匹配它。

雖然TypeScript 2.0不強制基於泛型參數的類型,但如果直接指定參數的類型,則會出現編譯器錯誤。方法參數的語義也保持不變。

interface ITopData { 
    // the interface must have at least one mandatory property, 
    // otherwise any object will match it 
    foo: number; 
} 

abstract class foo{ 
    constructor() { } 

    abstract test(data: ITopData): void; 
} 

interface IBottomData extends ITopData { } 

class bottom extends foo { 
    constructor() { super() } 

    test(data: IBottomData) { return } 
} 

class bad extends foo { 
    constructor() { super() } 

    test(data: string) { return; } 
} 

或者,指定類的泛型類型而不是方法。這樣,只要類型不匹配,您也會收到編譯器錯誤

interface ITopData { 
    // the interface must have at least one mandatory property, 
    // otherwise any object will match it 
    foo: number; 
} 

abstract class foo<T extends ITopData>{ 
    constructor() { } 

    abstract test(data: T): void; 
} 

interface IBottomData extends ITopData { } 

class bad1 extends foo<IBottomData> { 
    constructor() { super() } 

    test(data: string) { return } 
} 

class bad2 extends foo<string> { 
    constructor() { super() } 

    test(data: string) { return; } 
} 
+0

謝謝你,這是非常有幫助的。我試圖按照標記界面模式,並將ITopData留空,但我現在看到如何與其他類型匹配會導致錯誤。謝謝你的建議 :) – Jake