轉發 TypeScript基礎入門之模塊(一)html
關於術語的一點說明: 請務必注意一點,TypeScript 1.5裏術語名已經發生了變化。 "內部模塊"如今稱作"命名空間"。 "外部模塊"如今則簡稱爲"模塊",這是爲了與 ECMAScript 2015裏的術語保持一致,(也就是說 module X { 至關於如今推薦的寫法 namespace X {)。函數
從ECMAScript 2015開始,JavaScript引入了模塊的概念。TypeScript也沿用這個概念。ui
模塊在其自身的做用域裏執行,而不是在全局做用域裏;這意味着定義在一個模塊裏的變量,函數,類等等在模塊外部是不可見的,除非你明確地使用export形式之一導出它們。 相反,若是想使用其它模塊導出的變量,函數,類,接口等的時候,你必需要導入它們,可使用import形式之一。spa
模塊是自聲明的;兩個模塊之間的關係是經過在文件級別上使用imports和exports創建的。code
模塊使用模塊加載器去導入其它的模塊。 在運行時,模塊加載器的做用是在執行此模塊代碼前去查找並執行這個模塊的全部依賴。 你們最熟知的JavaScript模塊加載器是服務於Node.js的 CommonJS和服務於Web應用的Require.js。htm
TypeScript與ECMAScript 2015同樣,任何包含頂級import或者export的文件都被當成一個模塊。相反地,若是一個文件不帶有頂級的import或者export聲明,那麼它的內容被視爲全局可見的(所以對模塊也是可見的)。對象
任何聲明(好比變量,函數,類,類型別名或接口)都可以經過添加export關鍵字來導出。blog
Validation.ts接口
export interface StringValidator { isAcceptable(s: string): boolean; }
ZipCodeValidator.tsip
export const numberRegexp = /^[0-9]+$/; export class ZipCodeValidator implements StringValidator { isAcceptable(s: string): boolean { return s.length === 5 && numberRegexp.test(s); } }
導出語句很便利,由於咱們可能須要對導出的部分重命名,因此上面的例子能夠這樣改寫:
export const numberRegexp = /^[0-9]+$/; class ZipCodeValidator implements StringValidator { isAcceptable(s: string): boolean { return s.length === 5 && numberRegexp.test(s); } } export { ZipCodeValidator }; export { ZipCodeValidator as mainValidator }
咱們常常會去擴展其它模塊,而且只導出那個模塊的部份內容。 從新導出功能並不會在當前模塊導入那個模塊或定義一個新的局部變量。
ParseIntBasedZipCodeValidator.ts
export class ParseIntBasedZipCodeValidator { isAcceptable(s: string): boolean { return s.length === 5 && parseInt(s).toString() === s; } } export { ZipCodeValidator as RegExpBaseZipCodeValidator } from './ZipCodeValidator';
或者一個模塊能夠包裹多個模塊,並把他們導出的內容聯合在一塊兒經過語法:export * from "module"。
AllValidators.ts
export * from "./StringValidator"; // exports interface 'StringValidator' export * from "./ZipCodeValidator"; // exports class 'ZipCodeValidator'
模塊的導入操做與導出同樣簡單。 可使用如下import形式之一來導入其它模塊中的導出內容。
導入一個模塊中的某個導出內容
import { ZipCodeValidator } from "./ZipCodeValidator"; let myValidator = new ZipCodeValidator();
能夠對導入內容重命名
import { ZipCodeValidator as ZCV } from "./ZipCodeValidator"; let myValidator = new ZCV();
將整個模塊導入到一個變量,並經過它來訪問模塊的導出部分
import * as validator from "./ZipCodeValidator"; let myValidator = new validator.ZipCodeValidator();
具備反作用的導入模塊
儘管不推薦這麼作,一些模塊會設置一些全局狀態供其它模塊使用。 這些模塊可能沒有任何的導出或用戶根本就不關注它的導出。 使用下面的方法來導入這類模塊:
import "./my-module.js";
每一個模塊均可以有一個default導出。 默認導出使用 default關鍵字標記;而且一個模塊只可以有一個default導出。 須要使用一種特殊的導入形式來導入 default導出。
default導出十分便利。 好比,像JQuery這樣的類庫可能有一個默認導出 jQuery或$,而且咱們基本上也會使用一樣的名字jQuery或$導出JQuery。
JQuery.d.ts
declare let $: JQuery; export default $;
App.ts
import $ from "JQuery"; $("button.continue").html( "Next Step..." );
類和函數聲明能夠直接被標記爲默認導出。 標記爲默認導出的類和函數的名字是能夠省略的。
ZipCodeValidator.ts
export default class ZipCodeValidator { static numberRegexp = /^[0-9]+$/; isAcceptable(s: string) { return s.length === 5 && ZipCodeValidator.numberRegexp.test(s); } }
Test.ts
import validator from "./ZipCodeValidator"; let myValidator = new validator();
或者
StaticZipCodeValidator.ts
const numberRegexp = /^[0-9]+$/; export default function (s: string) { return s.length === 5 && numberRegexp.test(s); }
Test.ts
import validate from "./StaticZipCodeValidator"; let strings = ["Hello", "98052", "101"]; // Use function validate strings.forEach(s => { console.log(`"${s}" ${validate(s) ? " matches" : " does not match"}`); });
default導出也能夠是一個值
OneTwoThree.ts
export default "123";
Log.ts
import num from "./OneTwoThree"; console.log(num); // "123"
export =和 import = require()
CommonJS和AMD都有一個exports對象的概念,它包含了一個模塊的全部導出內容。
它們也支持把exports替換爲一個自定義對象。 默認導出就比如這樣一個功能;然而,它們卻並不相互兼容。 TypeScript模塊支持 export =語法以支持傳統的CommonJS和AMD的工做流模型。
export =語法定義一個模塊的導出對象。 它能夠是類,接口,命名空間,函數或枚舉。
若要導入一個使用了export =的模塊時,必須使用TypeScript提供的特定語法import module = require("module")。
ZipCodeValidator.ts
let numberRegexp = /^[0-9]+$/; class ZipCodeValidator { isAcceptable(s: string) { return s.length === 5 && numberRegexp.test(s); } } export = ZipCodeValidator;
Test.ts
import zip = require("./ZipCodeValidator"); // 嘗試一些字符 let strings = ["Hello", "98052", "101"]; // 使用validator let validator = new zip(); // 檢測每一個字符串,是否經過驗證 strings.forEach(s => { console.log(`"${ s }" - ${ validator.isAcceptable(s) ? "matches" : "does not match" }`); });