【TypeScript】TypeScript 学习 4——模块
前端数据验证在改善用户体验上有很大作用,在学了之前的知识的时候,我们很可能会写出以下代码:
interface StringValidator {
    isAcceptable(s: string): boolean;
}
var lettersRegexp = /^[A-Za-z]+$/;
var numberRegexp = /^[0-9]+$/;
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);
    }
}
// Some samples to try
var strings = ['Hello', '98052', '101'];
// Validators to use
var validators: { [s: string]: StringValidator; } = {};
validators['ZIP code'] = new ZipCodeValidator();
validators['Letters only'] = new 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);
    }
});
那么这段代码最大的问题是什么呢?一个是没法复用,验证的封装和验证过程在同一个文件,验证的封装已经是可以复用的。另一个是接口和两个实现的类都直接挂接在全局变量上,假如数量一多的话,将会污染整个全局变量。
模块化就是为了解决这一问题而诞生的。
module 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);
    }
});
我们使用 module 关键字来定义模块,用 export 关键字让我们的接口、类等成员对模块外可见。
这样,就只有模块名挂接在全局变量上,最大限度地避免污染全局变量了。
- 分隔模块到多个文件
随着我们项目的扩展,我们的代码总不可能只写在一个文件里。为了更好地维护项目,我们会将特定功能放到一个文件里,然后加载多个功能实现我们想需要的功能。现在我们先将上面的代码分割到多个文件里。
Validation.ts
module Validation {
    export interface StringValidator {
        isAcceptable(s: string): boolean;
    }
}
LettersOnlyValidator.ts
/// <reference path="Validation.ts" />
module Validation {
var lettersRegexp = /^[A-Za-z]+$/;
export class LettersOnlyValidator implements StringValidator {
isAcceptable(s: string) {
return lettersRegexp.test(s);
}
}
}
ZipCodeValidator.ts
/// <reference path="Validation.ts" />
module 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);
}
});
在项目中新建好以上四个文件,然后我们编译项目,如果我们代码编写没错的话,是能够编译通过的。另外,我们可以见到后面三个文件开头有类似于 C# 的文档注释,这是告诉 TypeScript 编译器该文件依赖于哪些文件,假如依赖的文件不存在的话,编译就会不通过。当然我们不写也是可以的,只不过编译器在编译时不会帮我们检查,一般来说,还是建议写上。
另外,在引用编译生成的 JavaScript 文件时,我们需要注意好顺序。以上面的代码为例,我们在 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" />
- 外部模块
在上面的方式中,浏览器会把 4 个 JavaScript 都加载。但某些时候,我们并不需要全部都用上,应该实现按需加载。那么在 TypeScript 中如何实现呢,很简单,只需要稍微修改一下就行。
Validation.ts
export interface StringValidator {
    isAcceptable(s: string): boolean;
}
LettersOnlyValidator.ts
import validation = require('./Validation');
var lettersRegexp = /^[A-Za-z]+$/;
export class LettersOnlyValidator implements validation.StringValidator {
    isAcceptable(s: string) {
        return lettersRegexp.test(s);
    }
}
ZipCodeValidator.ts
import validation = require('./Validation');
var numberRegexp = /^[0-9]+$/;
export class ZipCodeValidator implements validation.StringValidator {
    isAcceptable(s: string) {
        return s.length === 5 && numberRegexp.test(s);
    }
}
Test.ts
import validation = require('./Validation');
import zip = require('./ZipCodeValidator');
import letters = require('./LettersOnlyValidator');
// Some samples to try
var strings = ['Hello', '98052', '101'];
// Validators to use
var validators: { [s: string]: validation.StringValidator; } = {};
validators['ZIP code'] = new zip.ZipCodeValidator();
validators['Letters only'] = new letters.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);
    }
});
修改完之后,编译。。。不通过!
看官们可能觉得我坑爹了,辛辛苦苦敲这么一大段后,竟然编译不通过。这里,我们先说说模块加载的两种规范。
CommonJS 规范:
CommonJS 目标在于实现一个类似于 Python、Ruby 等语言的标准库。而 NodeJS 使用的就是这一规范。
var m = require('mod');
exports.t = m.something + 1;
AMD 规范:
由于上面的 CommonJS 规范所实现的加载是同步的,但实际上,我们的浏览器更需要的是异步加载,因此 AMD 规范应运而生。
define(["require", "exports", 'mod'], function(require, exports, m) {
    exports.t = m.something + 1;
});
那么 TypeScript 使用哪种规范呢?答案是两种都可以,看需要选择其中一种。
回到我们的项目,修改项目属性。

将这里修改为 AMD 或者 CommonJS,然后就可以通过编译了。
- Export =
在上面的代码中,我们导出模块的根是文件,因此需要写成 zip.ZipCodeValidator 这种形式,那为什么不简化一下呢?直接用 ZipCodeValidator 多好。Export = 就可以帮助我们做这件事。
Validation.ts
export interface StringValidator {
    isAcceptable(s: string): boolean;
}
LettersOnlyValidator.ts
import validation = require('./Validation');
var lettersRegexp = /^[A-Za-z]+$/;
class LettersOnlyValidator implements validation.StringValidator {
    isAcceptable(s: string) {
        return lettersRegexp.test(s);
    }
}
export = LettersOnlyValidator;
ZipCodeValidator.ts
import validation = require('./Validation');
var numberRegexp = /^[0-9]+$/;
class ZipCodeValidator implements validation.StringValidator {
    isAcceptable(s: string) {
        return s.length === 5 && numberRegexp.test(s);
    }
}
export = ZipCodeValidator;
Test.ts
import validation = require('./Validation');
import zipValidator = require('./ZipCodeValidator');
import lettersValidator = require('./LettersOnlyValidator');
// Some samples to try
var strings = ['Hello', '98052', '101'];
// Validators to use
var validators: { [s: string]: validation.StringValidator; } = {};
validators['ZIP code'] = new zipValidator();
validators['Letters only'] = new lettersValidator();
// 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);
    }
});
- 别名
module Shapes {
    export module Polygons {
        export class Triangle { }
        export class Square { }
    }
}
import polygons = Shapes.Polygons;
var sq = new polygons.Square(); // Same as 'new Shapes.Polygons.Square()'
这样写 import,下面的代码就可以简写一下。需要注意的是,不支持 require 引入的模块。
- declare 关键字
有时候我们需要定义全局变量,那么我们就需要增加 declare 关键字。
declare ver myString;
那么 myString 变量就是全局的了。这功能在定义全局模块时很有作用。
【TypeScript】TypeScript 学习 4——模块的更多相关文章
- typescript handbook 学习笔记4
		概述 这是我学习typescript的笔记.写这个笔记的原因主要有2个,一个是熟悉相关的写法:另一个是理清其中一些晦涩的东西.供以后开发时参考,相信对其他人也有用. 学习typescript建议直接看 ... 
- typescript handbook 学习笔记3
		概述 这是我学习typescript的笔记.写这个笔记的原因主要有2个,一个是熟悉相关的写法:另一个是理清其中一些晦涩的东西.供以后开发时参考,相信对其他人也有用. 学习typescript建议直接看 ... 
- typescript handbook 学习笔记2
		概述 这是我学习typescript的笔记.写这个笔记的原因主要有2个,一个是熟悉相关的写法:另一个是理清其中一些晦涩的东西.供以后开发时参考,相信对其他人也有用. 学习typescript建议直接看 ... 
- [TypeScript] TypeScript对象转JSON字符串范例
		[TypeScript] TypeScript对象转JSON字符串范例 Playground http://tinyurl.com/njbrnrv Samples class DataTable { ... 
- Python学习--Selenium模块
		1. Python学习--Selenium模块介绍(1) 2.Python学习--Selenium模块学习(2) 其他: 1. Python学习--打码平台 
- Python学习--Selenium模块学习(2)
		Selenium的基本操作 获取浏览器驱动寻找方式 1. 通过手动指定浏览器驱动路径2. 通过 `$PATH`环境变量找寻浏览器驱动 可参考Python学习--Selenium模块简单介绍(1) 控制 ... 
- Node学习HTTP模块(HTTP 服务器与客户端)
		Node学习HTTP模块(HTTP 服务器与客户端) Node.js 标准库提供了 http 模块,其中封装了一个高效的 HTTP 服务器和一个简易的HTTP 客户端.http.Server 是一个基 ... 
- Python学习---重点模块的学习【all】
		time [时间模块] import time # print(help(time)) # time模块的帮助 print(time.time()) # 时间戳 print(time.cloc ... 
- python学习——常用模块
		在学习常用模块时我们应该知道模块和包是什么,关于模块和包会单独写一篇随笔,下面先来了解有关在python中的几个常用模块. 一.什么是模块 常见的场景:一个模块就是一个包含了python定义和声明的文 ... 
- python学习之模块导入,操作邮件,redis
		python基础学习06 模块导入 导入模块的顺序 1.先从当前目录下找 2.当前目录下找不到,再从环境变量中找,如果在同时在当前目录和环境变量中建立相同的py文件,优先使用当前目录下的 导入模块的实 ... 
随机推荐
- Bioconductor应用领域之基因芯片
			引用自https://mp.weixin.qq.com/s?__biz=MzU4NjU4ODQ2MQ==&mid=2247484662&idx=1&sn=194668553f9 ... 
- java 注解  基本原理 编程实现
			摘要: java 1.5开始引入了注解和反射,正确的来说注解是反射的一部分,没有反射,注解无法正常使用,但离开注解,反射依旧可以使用,因此来说,反射的定义应该包含注解才合理一些. java 1.5开始 ... 
- distinct top執行順序
			select distinct top 3 from table; 先distinct后top 
- myeclipse 10激活,本人已测试过可行
			激活步骤: 下载myeclipse 10硬解程序包: ed2k://|file|%5Bmyeclipse.10.0.%E6%9B%B4%E6%96%B0%E5%8F%91%E5%B8%83%28%E7 ... 
- discrete
			discrete - 必应词典 美[dɪ'skrit]英[dɪ'skriːt] adj.离散的:分离的:各别的 网络不连续的:分立的:离散型 
- Python threading 单线程 timer重复调用函数
			项目中需要使用定时器,每次都使用构造器函数调用: timer = threading.Timer(timerFlag, upload_position) timer.start() 打印线程后发现,每 ... 
- 16-图片上传那些事 org.springframework.web.multipart.MultipartException: The current request is not a multipart request
			https://blog.csdn.net/u010974598/article/details/46458039 我曾尝试了: @RequestMapping(value="/user/r ... 
- ADF 入门帮助
			本文是由英文帮助翻译所得: 1>task flows “任务流 task flows”可以包括非可视化的组件,比如方法调用.“页片段 page fragment”可以运行在一个页面的某个局部区域 ... 
- 简单的几个Boost定时器
			boost的asio库里有几个定时的器,老的有 deadline_timer , 还有三个可配合 C++11 的 chrono 使用的 high_resolution_timer . steady_ ... 
- [Selenium]当DOM结构里面有iFrame,iFrame里面是html,怎么send keys to 里面的body,怎么用Assert进行验证?
			我在测试的过程中遇到一个这样的问题,我无法通过CssSelector找到iFrame下边的html: <div id="mailEditorDiv" style=" ... 
