2015-09-15 21 views
0

我創建了簡單的打字稿文件 - playground link模塊合併 - 它是如何工作的?

module Animals { 
    export class Zebra { } 
} 
module Animals { 
    export interface Legged { numberOfLegs: number; } 
    export class Dog { } 
} 

從我的觀點是等同於:

module Animals { 
    export class Zebra { } 
    export interface Legged { numberOfLegs: number; } 
    export class Dog { } 
} 

,應該產生:

var Animals; 
(function (Animals) { 
    var Zebra = (function() { 
     function Zebra() { 
     } 
     return Zebra; 
    })(); 
    Animals.Zebra = Zebra; 
    var Dog = (function() { 
     function Dog() { 
     } 
     return Dog; 
    })(); 
    Animals.Dog = Dog; 
})(Animals || (Animals = {})); 

但在操場上,你可以看到,它產生兩個Animals變量,即處理它作爲獨立的命名空間。

它是正確的嗎?據handbook應該合併...

編輯

旁註根據定義文件(d.ts) - 當我運行TSC與生成--declaration開關下面的定義。模塊動物包括兩次。這是對的嗎?

declare module Animals { 
    class Zebra { 
    } 
} 
declare module Animals { 
    interface Legged { 
     numberOfLegs: number; 
    } 
    class Dog { 
    } 
} 

回答

1

但是在操場上,您可以看到它會生成兩個動物變量,即將其視爲單獨的名稱空間。

它確實會生成兩個變量(請參閱「爲什麼生成兩個函數,而不是一個」link)。然而,它仍然是一個單個命名空間(通知Animals || (Animals = {}表示如果可用,它將繼承以前的值)。

根據手冊它應該合併

它們合併。生成的代碼確保(使用Animals || (Animals = {}Animals繼承第一個模塊聲明。該手冊不說它如何管理合併(this does)。

+0

看來我誤解了模塊合併的工作原理。但對我來說,這仍然很奇怪。如果我在一個模塊中有100多個文件,那麼變量會重複100次? – Kai

+0

另外,當我嘗試從我的所有文件生成定義時,單個d。ts文件包含多個具有相同名稱的模塊,並且VSCode聲明這是一個錯誤 – Kai

+1

好吧,關閉question.Besides,@basarat謝謝你在打字稿上的工作 – Kai

1

儘管typescript編譯器會合並兩個模塊的類型,但是這些類型不再存在於編譯的javascript中(從類型安全角度來看)。在javasript中,只有模塊的實現很重要,所以實現的合併在運行時發生。

這兩個var Animals聲明不衝突,並且將成員添加到動物模塊的每個函數都使用(Animals || (Animals = {})調用。它將使用Animals變量的當前值,或將Animals設置爲一個新的空對象,然後使用它。

這種情況在運行時發生的事實很重要,因爲它允許您擴展在您正在處理的文件之外創建的對象。例如,您可以使用相同的語法擴展內建對象。查看this playground example瞭解它如何與內置對象合作。