typescript中的namespace和modules(譯)

介紹

這篇文章概述了多種在typescript中,使用namespaces和modules組織代碼的方式,咱們將會重溫一些進階的如何使用namespaces和modules的主題,還有處理一些在typescript中使用它們時的一些陷阱javascript

使用Namespaces

Namespaces簡化了js對象在全局命名空間裏的命名,這使得namespaces能夠很容易的去構造使用。它們能夠跨越多個文件,也能夠經過使用--outFile標識去串聯起來使用。Namespaces在web程序中是一種很好的組織代碼的方式,把全部的依賴包含進script標籤插入到你的html頁面上。html

像全部的全局命名空間污染同樣,它很難去肯定組件的依賴,尤爲是在一個大型的應用程序中java

使用Modules

和namespaces相似,modules既能夠包含代碼也能夠包含聲明。二者最主要的區別就是modules聲明瞭它的依賴node

modules依賴於模塊加載器(好比CommonJs或者Require.js),對於小型的JS應用來講,modules或許不是最佳實踐,可是對於大型應用來講,這裏所耗費的成本同時也帶來了代碼的模塊及良好的可維護性的好處。modules提供了更好的代碼複用,強做用域隔離和更好的打包工具支持。web

值得一提的是,對於nodejs應用來講,modules已經做爲組織代碼的默認方式typescript

從ECMAScript 2015開始,modules已經做爲內置的一部分,經過全部遵循規範的引擎實現都應該已經支持modules,這樣,對於新項目來講,modules已是組織代碼的標配工具

namespaces和modules的使用陷阱

在這個章節中,咱們將介紹幾個比較常見的在使用namespaces和modules的陷阱,還有就是如何避免這些陷阱ui

-ing a module

一個比較常見的錯誤就是,試圖使用"/// <reference ... />"語法來引用一個模塊文件,而不是使用import聲明語句。爲了理解這二者的區別,咱們首先須要明白如何讓編譯器能夠鎖定基於此路徑的模塊的類型信息。好比「import x from ...」中的...spa

編譯器會嘗試在相應的路徑下查找.ts, .tsx和.d.ts文件,若是指定的文件並無被找到,編譯器就會去其餘的模塊聲明文件中去查找。code

  • 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";
複製代碼

這裏的reference tag容許咱們去定位這個包含了這個模塊聲明的文件

不必的Namespacing

若是你正在轉化一個程序從namespaces到modules,這個過程會很是簡單,相似於下面文件這樣

  • shapes.ts
export namespace Shapes {
    export class Triangle { /* ... */ }
    export class Square { /* ... */ }
  }
複製代碼

這裏頂層的module Shapes毫無緣由的包裝了Triangle和Square,這會讓使用你模塊的人比較迷惑

  • shapeConsumer.ts
import * as shapes from "./shapes";
  let t = new shapes.Shapes.Triangle(); // shapes.Shapes?
複製代碼

typescript中模塊的一個關鍵特性就是,兩個不一樣的模塊毫不會賦予名稱給相同的做用域,由於模塊的消費者決定了該分配什麼名稱,不必主動在一個namesapce中去包裹導出的標記

爲了解釋爲何你不該該在你的模塊內容中用namespace來包裹,通常來講namesapce會提供合理的構造分組,防止命名衝突,因爲模塊文件自身已是一個合理的分組,它的頂層名稱經過import的代碼來定義,因此對於對於導出的對象不必再去包裝額外的模塊層。

下面是一個改進版的例子:

  • shapes.ts
export class Triangle { /* ... */ }
  export class Square { /* ... */ }
複製代碼
  • shapeConsumer.ts
import * as shapes from "./shapes";
  let t = new shapes.Triangle();
複製代碼

模塊的權衡

正如在js文件和modules之間是一對一的關係,在typescript中模塊源文件和它們對應的最終生成文件之間也是一對一的關係,這樣所帶來的影響就是根據目標的模塊系統不能將多個模塊源文件鏈接起來。當你的模塊目標是commonjs或umd時,你不能使用outFile這個選項來輸出文件,但隨着typescript1.8及更高版本的發佈,當目標target爲amd或是system時就有可能能夠使用outFile選項

參考

typescript

相關文章
相關標籤/搜索