TypeScript基礎入門之名稱空間和模組
名稱空間和模組
關於術語的說明:值得注意的是,在TypeScript 1.5中,命名法已經改變。
"內部模組"現在是"名稱空間"。
"外部模組"現在只是"模組",以便與ECMAScript 2015的術語保持一致(即module X {相當於現在首選的namespace X {)。
介紹
本文概述了使用TypeScript中的名稱空間和模組組織程式碼的各種方法。
我們還將討論如何使用名稱空間和模組的一些高階主題,並解決在TypeScript中使用它們時常見的一些陷阱。
有關模組的更多資訊,請參閱模組文件。
有關名稱空間的更多資訊,請參閱名稱空間文件。
使用名稱空間
名稱空間只是全域性名稱空間中的JavaScript物件。
這使名稱空間成為一個非常簡單的構造。
它們可以跨多個檔案,並且可以使用--outFile連線。
名稱空間可以是在Web應用程式中構建程式碼的好方法,所有依賴項都包含在HTML頁面中的<script>標記中。
就像所有全域性名稱空間汙染一樣,很難識別元件依賴性,尤其是在大型應用程式中。
使用模組
就像名稱空間一樣,模組可以包含程式碼和宣告。
主要區別在於模組聲明瞭它們的依賴關係。
模組還依賴於模組載入器(例如CommonJs/Require.js)。
對於小型JS應用程式而言,這可能不是最佳選擇,但對於大型應用程式,成本具有長期模組化和可維護性優勢。
模組為捆綁提供了更好的程式碼重用,更強的隔離和更好的工具支援。
值得注意的是,對於Node.js應用程式,模組是構造程式碼的預設方法和推薦方法。
從ECMAScript 2015開始,模組是該語言的本機部分,並且應該受到所有相容引擎實現的支援。
因此,對於新專案,模組將是推薦的程式碼組織機制。
名稱空間和模組的缺陷
下面我們將描述使用名稱空間和模組時的各種常見缺陷,以及如何避免它們。
/// <reference>-ing a module
一個常見的錯誤是嘗試使用/// <reference ... /> 語法來引用模組檔案,而不是使用import語句。
為了理解這種區別,我們首先需要了解編譯器如何根據匯入的路徑找到模組的型別資訊(例如...在,import x from "...";import x = require("..."); 等等。路徑。
編譯器將嘗試使用適當的路徑查詢.ts,.tsx和.d.ts。
如果找不到特定檔案,則編譯器將查詢環境模組宣告。
回想一下,這些需要在.d.ts檔案中宣告。
myModules.d.ts
// In a .d.ts file or .ts file that is not a module: declare module "SomeModule" { export function fn(): string; }
myOtherModule.ts
/// <reference path="myModules.d.ts" /> import * as m from "SomeModule";
這裡的引用標記允許我們找到包含環境模組宣告的宣告檔案。
這就是使用幾個TypeScript示例使用的node.d.ts檔案的方式。
無需名稱空間
如果您要將程式從名稱空間轉換為模組,則可以很容易地得到如下所示的檔案:
shapes.ts
export namespace Shapes { export class Triangle { /* ... */ } export class Square { /* ... */ } }
這裡的頂級模組Shapes無緣無故地包裝了Triangle和Square。
這對您的模組的消費者來說是令人困惑和惱人的:
shapeConsumer.ts
import * as shapes from "./shapes"; let t = new shapes.Shapes.Triangle(); // shapes.Shapes?
TypeScript中模組的一個關鍵特性是兩個不同的模組永遠不會為同一範圍提供名稱。
因為模組的使用者決定分配它的名稱,所以不需要主動地將名稱空間中的匯出符號包裝起來。
為了重申您不應該嘗試命名模組內容的原因,名稱空間的一般概念是提供構造的邏輯分組並防止名稱衝突。
由於模組檔案本身已經是邏輯分組,並且其頂級名稱由匯入它的程式碼定義,因此不必為匯出的物件使用其他模組層。
這是一個修改過的例子:
shapes.ts
export class Triangle { /* ... */ } export class Square { /* ... */ }
shapeConsumer.ts
import * as shapes from "./shapes"; let t = new shapes.Triangle();
模組的權衡
正如JS檔案和模組之間存在一對一的對應關係一樣,TypeScript在模組原始檔與其發出的JS檔案之間具有一對一的對應關係。
這樣做的一個結果是,根據您定位的模組系統,無法連線多個模組原始檔。
例如,在定位commonjs或umd時不能使用outFile選項,但使用TypeScript 1.8及更高版本時,可以在定位amd或system時使用outFile。