2017-07-27 52 views
0
interface IHuman { 
    talk(): void; 
    walk(): void; 
} 

class Human implements IHuman { 
    talk() { 
    } 

    walk() { 
    } 

    // This should not be possible: 
    fly() { 
    } 
} 

有沒有辦法告訴編譯器只允許添加接口中定義的公共方法?禁止添加比接口更多的公共方法

換句話說,在某些情況下禁用鴨子打字?

+1

AFAIK,no。基本原理是什麼?另外,這與鴨子打字無關。強類型語言(Java等)也授權在實現接口的類中使用更多的方法。否則他們將是無用的。 –

+0

其基本原理是確保每個人都使用接口代替整個代碼庫中的實現。 – kraftwer1

回答

0

您在尋找exact types,TypeScript目前沒有(截至TS 2.4)。看起來似乎沒有即時計劃來實現它,因爲它可能會與類型檢查器如何處理泛型相互作用。如果您認爲您的使用案例足夠吸引人,您可能需要對the issue in GitHub發表評論。


也許你可以用不同的方式得到你想要的東西?例如,

type Constructor<T> = { 
    new (...args: any[]): T; 
    readonly prototype: T; 
} 

// your interface is now a class 
class IHuman { 
    talk():void {throw new Error("nope")} 
    walk():void {throw new Error("sorry")} 
    private constructor() { 
    // nobody can subclass or instantiate IHuman from outside 
    } 
    static implement(talkImpl:() => void, walkImpl:() => void): Constructor<IHuman> { 
    return class extends IHuman { 
     talk() { 
     talkImpl(); 
     } 
     walk() { 
     walkImpl(); 
     } 
     constructor() { 
     super(); 
     } 
    } 
    } 
}   

var Human = IHuman.implement(
() => { console.log('Hello!') }, 
() => { console.log("I'm walkin', here!") } 
); 
var human = new Human(); 
human.talk(); 
human.walk(); 

這將迫使任何人誰想要得到的IHuman子類調用IHuman.implement()這將只允許呼叫者實施talk()walk()方法。這對所有參與者來說可能都是不愉快的,但它可能是現在最接近的。

+0

感謝提示[確切類型](https://github.com/Microsoft/TypeScript/issues/12936)! – kraftwer1