Typescript-module(1)

typescript之旅

1.TypeScript-Basic
2.TypeScript interface
3.Typescript-module(1)
4.TypeScript Modules(2)
5.Typescript tsconfig
6.TypeScript Functions
7.Typescript Classjavascript

Namespace

模塊化開發是咱們組織代碼或團隊開發最重要的一課。你想一想,以一個相似於processon的在線畫圖系統爲例。若是UML節點的繪製,Canvas畫布的操做,鼠標事件,快捷鍵事件,各類約束條件的加入,這麼一個上萬行的文件,打開文件要2分鐘,找一行代碼都得3分鐘,還怎麼維護?若是我想加一個變量,本身鐘意的變量名和前人的衝突,最後只能委屈的用了一個不合適的名稱,代碼愈來愈難看懂,整夜整夜加班。html

第一步

以一個例子說明,在網頁中常常須要檢驗用戶的輸入是否合法,咱們寫了一個簡單的字符串校驗器。java

var lettersRegexp = /^[A-Za-z]+$/;
var numberRegexp = /^[0-9]+$/;

interface StringValidator {
    isAcceptable(s: string): boolean;
}

class LettersOnlyValidator implements StringValidator {
    isAcceptable(s: string) {
        return lettersRegexp.test(s);
    }
}

class ZipCodeValidator implements StringValidator {
    isAcceptable(s: string) {
        return s.length === 5 && numberRegexp.test(s);
    }
}

解決之道模塊化chrome

namespace關鍵字

解決問題: 劃分命名空間typescript

namespace Validation {
    export interface StringValidator {
        isAcceptable(s: string): boolean;
    }

    var lettersRegexp = /^[A-Za-z]+$/;
    var numberRegexp = /^[0-9]+$/;

    export class LettersOnlyValidator implements StringValidator {
        isAcceptable(s: string) {
            return lettersRegexp.test(s);
        }
    }

    export class ZipCodeValidator implements StringValidator {
        isAcceptable(s: string) {
            return s.length === 5 && numberRegexp.test(s);
        }
    }
}

// Some samples to try
var strings = ['Hello', '98052', '101'];
// Validators to use
var validators: { [s: string]: Validation.StringValidator; } = {};
validators['ZIP code'] = new Validation.ZipCodeValidator();
validators['Letters only'] = new Validation.LettersOnlyValidator();
// Show whether each string passed each validator
strings.forEach(s => {
    for (var name in validators) {
        console.log('"' + s + '" ' + (validators[name].isAcceptable(s) ? ' matches ' : ' does not match ') + name);
    }
});
  • 咱們把跟類型校驗相關的全部聲明或變量放到一個叫作Validation的命名空間(這裏使用的是namespace Validation ,也可使用module Validation,推薦使用前者-namespace)。segmentfault

  • namespace至關於一個封閉的module,如何使用裏面的聲明或變量呢?export關鍵字可使interface,class等在外部可見。而變量lettersRegexpnumberRegexp外部不可見。模塊化

namespace Validation {
    export interface StringValidator {
        isAcceptable(s: string): boolean;
    }

    var lettersRegexp = /^[A-Za-z]+$/;
    var numberRegexp = /^[0-9]+$/;

    export class LettersOnlyValidator implements StringValidator {
        isAcceptable(s: string) {
            return lettersRegexp.test(s);
        }
    }

    export class ZipCodeValidator implements StringValidator {
        isAcceptable(s: string) {
            return s.length === 5 && numberRegexp.test(s);
        }
    }
}

// Some samples to try
var strings = ['Hello', '98052', '101'];
// Validators to use
var validators: { [s: string]: Validation.StringValidator; } = {};
validators['ZIP code'] = new Validation.ZipCodeValidator();
validators['Letters only'] = new Validation.LettersOnlyValidator();
// Show whether each string passed each validator
strings.forEach(s => {
    for (var name in validators) {
        console.log('"' + s + '" ' + (validators[name].isAcceptable(s) ? ' matches ' : ' does not match ') + name);
    }
});

ok,咱們劃分了多個命名空間,如今能夠安心的使用變量名,不用擔憂和別人衝突了。可是上萬行的代碼怎麼分割成多個文件呢?(util工具函數一個文件,業務代碼一個文件,多清楚!)函數

分割代碼

Validation.ts工具

namespace Validation {
    export interface StringValidator {
        isAcceptable(s: string): boolean;
    }
}

LettersOnlyValidator.tsspa

/// <reference path="Validation.ts" />
namespace Validation {
    var lettersRegexp = /^[A-Za-z]+$/;
    export class LettersOnlyValidator implements StringValidator {
        isAcceptable(s: string) {
            return lettersRegexp.test(s);
        }
    }
}

ZipCodeValidator.ts

/// <reference path="Validation.ts" />
namespace Validation {
    var numberRegexp = /^[0-9]+$/;
    export class ZipCodeValidator implements StringValidator {
        isAcceptable(s: string) {
            return s.length === 5 && numberRegexp.test(s);
        }
    }
}

Test.ts

/// <reference path="Validation.ts" />
/// <reference path="LettersOnlyValidator.ts" />
/// <reference path="ZipCodeValidator.ts" />

// Some samples to try
var strings = ['Hello', '98052', '101'];
// Validators to use
var validators: { [s: string]: Validation.StringValidator; } = {};
validators['ZIP code'] = new Validation.ZipCodeValidator();
validators['Letters only'] = new Validation.LettersOnlyValidator();
// Show whether each string passed each validator
strings.forEach(s => {
    for (var name in validators) {
        console.log('"' + s + '" ' + (validators[name].isAcceptable(s) ? ' matches ' : ' does not match ') + name);
    }
});

注意
<reference path="Validation.ts" />若是沒有這句,你就沒法引用Validation.ts文件中聲明的class.好啦,我知道語法很奇葩,不過也有好處啊!

  • 一行命令編譯好
    tsc --out sample.js Test.ts

編譯器根據Test.ts中聲明的reference,順序地導入並編譯成一個文件sample.js

  • 有時候若是你有特殊需求,比方說不想合併這些文件,致使sample.js太長,在chrome developer tools中調試時,跳的太遠。你能夠分別編譯,而後再html中引入

<script src="Validation.js" type="text/javascript" />
    <script src="LettersOnlyValidator.js" type="text/javascript" />
    <script src="ZipCodeValidator.js" type="text/javascript" />
    <script src="Test.js" type="text/javascript" />
本站公眾號
   歡迎關注本站公眾號,獲取更多信息