2015-05-15 295 views
2

我試圖爲第三方庫創建一個定義文件(*.d.ts)。這個庫有一個基類,用戶對象最終將繼承它。但是,庫處理這些對象的構造,並將它們自己的內置方法與用戶定義的方法合併。因此,我不能只創建一個用戶類implementsinterface,因爲用戶類未定義基類的內置方法。TypeScript類接口定義

打字稿定義d.ts文件:

module otherlib { 
    export interface Base { 
     third_party_base_method(): string; 
    } 
} 

用戶源:

// FAILS because MyClass doesn't define third_party_base_method() 
class MyClass implements otherlib.Base { 
    myfunc() { 
     let str = this.third_party_base_method(); 
    } 
}  

一種解決方法我現在有是創建一個打字稿文件(*.ts),其限定了class而不是一個interface與所有基體類型中具有空體或返回虛擬值的方法。用戶類然後可以從extend這樣的類型檢查工作。但是,這看起來很不方便,導致不必要的和潛在危險的原型操作。有沒有更好的辦法?

打字稿.ts文件來定義第三方庫的基類:

module otherlib { 
    export class Base { 
     // Dummy stub definition that is never called 
     third_party_base_method(): string { return "dummy"; } 
    } 
} 

用戶來源:

class MyClass extends otherlib.Base { 
    myfunc() { 
     // Proper type checking for calling the method that the 
     // third party library adds to the object. 
     let str = this.third_party_base_method(); 
    } 
} 

UPDATE

我其實開始碰到一些與空的存根函數一起擴展的麻煩。所以,我的新的解決方法就是建立一個存根,使鑄件容易...

打字稿d.ts文件來定義第三方庫的基類:

module otherlib { 
    export interface Base { 
     third_party_base_method(): string; 
    } 
} 

打字稿.ts文件鑄造存根:

module otherlib_stub { 
    export class Base { 
     get base(): otherlib.Base { return <otherlib.Base><any>this; } 
    } 
} 

用戶來源:

class MyClass extends otherlib_stub.Base implements otherlib.Base { 
    myfunc() { 
     // Proper type checking for calling the method that the 
     // third party library adds to the object. 
     let str = this.base.third_party_base_method(); 
    } 
} 
+0

對於那些好奇的人,我正在處理的特定圖書館是Google的Polymer 0.9 – drarmstr

+0

您是否知道Definitely Typed? https://github.com/borisyankov/DefinitelyTyped/tree/master/polymer – Fenton

+0

聚合物在那裏的選項沒有被移植到0.9。另外,它並沒有真正提供創建一個適當的TypeScript類來傳遞給用戶方法中用於處理此上下文的鍵入。 – drarmstr

回答

0

你守ld使用環境聲明。這提供了類型的信息,但不會產生在JavaScript輸出的任何代碼:

declare module otherlib { 
    export class Base { 
     third_party_base_method(): string; 
    } 
} 

你可以把這個與.d.ts擴展名的文件,使之清楚,這不是一個實現文件。

更新!

這取決於第三方庫的工作方式,但您可以使用接口將外部成員和本地成員包裝爲單一類型。

下面的例子假設你調用一個返回你的擴展類的方法。如果您需要幫助確定其確切版本,您將不得不提供一個實際工作方式的示例。

declare module otherlib { 
    export interface Base { 
     third_party_base_method(): string; 
    } 

    export function externalCodeThatExtendsYourClass<T>(obj: any): T; 
} 

// You would need the class/interface pair for each class 
class Example { 
    yourMethod() { 
     alert('All yours'); 
    } 
} 

// The interface wraps the class members and the externally added members into a single type 
interface ExtendedExample extends Example, otherlib.Base { } 


var example = otherlib.externalCodeThatExtendsYourClass<ExtendedExample>(new Example()); 

example.third_party_base_method(); 
example.yourMethod(); 
+0

謝謝,但這沒有奏效。我可以定義抽象類Base,是的。但是當用戶類試圖執行Base時,TypeScript抱怨缺少'third_party_base_method'。 – drarmstr

+0

您可能需要發佈另一個問題,因爲它在這裏工作:http://bit.ly/1eanPkc – Fenton

+0

通過使用'擴展otherlib.Base'它確實編譯。然而,問題在於,當你實際創建一個MyClass對象時,編譯後的JavaScript會嘗試實際擴展基於otherlib.Base的原型。由於第三方庫不是以這種方式創建對象的,因此這會導致運行時失敗。它構造並擴展了它們本身,顯然有一些不同的約定可以打破這一點。我也嘗試使用一些任意其他未使用的名稱空間進行環境描述。但是,'extend'在運行時也會失敗,因爲它沒有被定義。 – drarmstr