2015-08-08 49 views
3

我有幾個接口和類有一個可選選項對象:打字稿,準確地反映類方法的行爲

interface asObject { a: number, b: number } 

interface options { returnAs: string; } 

interface IA { 
    go(): string; 
    go(o: options): string | asObject; 
} 

class A implements IA { 
    public go(o?: options): string | asObject { 
     if(o&& o.returnAs && typeof o.returnAs === 'string') { 
      switch(o.returnAs) { 
       case 'object': 
        return { a: 5, b: 7 }; 
       default: 
        return 'string'; 

      } 
     } 
    } 
} 

而我得到的錯誤:「類A正確實現接口IA」。

如果我試圖重載方法:

... 
public go(): string; 
// Notice the parameter is no longer optional, ? removed. 
public go(o: options): string | asObject { /* implementation as above */ } 
... 

現在,我得到:「超載簽名不是與功能實現兼容」。

我知道我可以只取出IA接口上的重載簽名和刪除A類的重載方法:

// Interface IA, notice the parameter is now optional, ? added. 
go(o?: options): string | asObject; 
// Class A 
public go(o?: options): string | asObject { /* implementation as above */ } 

讓我解釋一下:

A類呼籲的方法go,如果go不提供選項對​​象,它將返回一個字符串,但是如果用戶提供了一個選項對象,則返回值取決於returnAs字段,即字符串或一個東西。

我的問題:

我不認爲我提供的解決方案代表準確go方法的行爲。

有沒有辦法保持準確的行爲,爲了打字稿的用法,沒有得到錯誤,就像我上面描述的前兩次嘗試一樣?

當我說準確的行爲我的意思是:

我正在尋找一種方式,其中打字稿就能推斷AObject類型string

var AObject = new A().go(); 

它就能推斷AObject如任一stringasObject

var AObject = new A().go({ returnAs: 'object|string' }); 

我不是100%肯定它可能在打字稿中,在那種情況下,我很樂意提供一個建議。

+0

不確定,您在做什麼。你爲什麼要同時擁有'asObject'和'string'對象?您可以使用'else'而不是2種方法,請參閱[示例](http://goo.gl/motrsx) –

回答

3

最簡單的方法是聲明A.go結果作爲any

public go(o?: options): any { 

或宣佈的功能接口:

interface asObject { a: number, b: number } 

interface options { returnAs: string; } 

interface IGoFunction { 
    (): string; 
    (o: options): string | asObject; 
} 

interface IA { 
    go: IGoFunction; 
} 

class A implements IA { 
    go = <IGoFunction>function (o?: options): string | asObject { 
     if (o && o.returnAs && typeof o.returnAs === 'string') { 
      switch (o.returnAs) { 
       case 'object': 
        return { a: 5, b: 7 }; 
       default: 
        return 'string'; 
      } 
     } 
    } 
} 

其實你甚至都不需要聲明一個名爲接口:

class A { 
    go = <{ 
     (): string; 
     (o: options): string | asObject; 
    }>function (o?: options): string | asObject { 
    ... 

缺點是功能增加每個實例A,但您可以明確將其添加到原型:

class A { 
    go: { 
     (): string; 
     (o: options): string | asObject; 
    }; 
} 

A.prototype.go = function (o?: options): any { 
... 
+0

嗨,謝謝,我非常喜歡這些示例和描述性解釋。 –