学习自:http://www.typescriptlang.org/Handbook#modules
首先定义一个文本格式检查器,可以查看输入的内容是否为字母或者数字
不使用模块
Validators.ts
interface StringValidator{
isAcceptable(s:string):boolean;
}
class ZipCodeValidator implements StringValidator{
zipRegexp:RegExp = /^\d{6}$/;
isAcceptable(zip:string){
return this.zipRegexp.test(zip);
}
}
class LettersValidator implements StringValidator{
lettersRegexp:RegExp = /^[a-zA-Z]+$/;
isAcceptable(letters:string){
return this.lettersRegexp.test(letters);
}
}
//待验证的字符串
var str = ['150000', 'hello', '一二三'];
var zipCodeValid:StringValidator = new ZipCodeValidator();
var lettersValid:StringValidator = new LettersValidator();
str.forEach(s=>{
if(zipCodeValid.isAcceptable(s)){
console.log(s+' 是邮政编码');
}else if(lettersValid.isAcceptable(s)){
console.log(s+' 是字母');
}else{
console.log(s+' 不知道是什么');
}
});
使用模块
上面代码看起来没有什么问题, 但是随着功能的增加, 我们可能需要加入更多的验证, 比如验证邮箱, 手机号, 身份信息等… 我们的代码会越来越大, 为了防止命名上的冲突, 变量或类的命名会越来越长,越来越复杂, 导致了维护的困难,全局变量的混乱.这时我们就会想到是否可以有效的组织我们的代码到不同的模块中,用模块划分功能.下面我们来改造一下上面的例子.
module Validator{
interface StringValidator{
isAcceptable(s:string):boolean;
}
export class ZipCodeValidator implements StringValidator{
zipRegexp:RegExp = /^\d{6}$/;
isAcceptable(zip:string){
return this.zipRegexp.test(zip);
}
}
export class LettersValidator implements StringValidator{
lettersRegexp:RegExp = /^[a-zA-Z]+$/;
isAcceptable(letters:string){
return this.lettersRegexp.test(letters);
}
}
}
var str = ['150000', 'hello', '一二三'];
var zipCodeVali = new Validator.ZipCodeValidator();
var lettersVali = new Validator.LettersValidator();
str.forEach(s=>{
if(zipCodeVali.isAcceptable(s)){
console.log(s+' 是邮政编码');
}else if(lettersVali.isAcceptable(s)){
console.log(s+' 是字母');
}else{
console.log(s+' 不知道是什么');
}
});
使用export
暴露想要对外提供的类或方法, StringValidator
因为是一个内部接口没必要让外部使用.
我们看使用模块改造后的例子,重点看module代码块,与前一个例子相比,全局变量减少到只有一个Validator
, 把StringValidator
,ZipCodeValidator
,LettersValidator
封装到模块内部, 这样有效的减少了对全局变量的污染,之后在加新的验证方法时只要放到模块内部即可.
划分模块
把所有逻辑放到一个页面中显然是不好的.我们来看一下如何组织我们的模块到不同的页面中.
validator.ts
module Validation {
export interface StringValidator{
isAcceptable(s:string):boolean;
}
}
zipCodeValidator.ts
/// <reference path="validator.ts" />
module Validation {
export class ZipCodeValidator implements StringValidator{
zipRegexp:RegExp = /^\d{6}$/;
isAcceptable(zip:string){
return this.zipRegexp.test(zip);
}
}
}
lettersValidator.ts
/// <reference path="validator.ts" />
module Validation{
export class LettersValidator implements StringValidator{
lettersRegexp:RegExp = /^[a-zA-Z]+$/;
isAcceptable(letters:string){
return this.lettersRegexp.test(letters);
}
}
}
test.ts
/// <reference path="validator.ts" />
/// <reference path="zipCodeValidator.ts" />
/// <reference path="lettersValidator.ts" />
var str = ['150000', 'hello', '一二三'];
var zipCodeVali = new Validation.ZipCodeValidator();
var lettersVali = new Validation.LettersValidator();
str.forEach(s=>{
if(zipCodeVali.isAcceptable(s)){
console.log(s+' 是邮政编码');
}else if(lettersVali.isAcceptable(s)){
console.log(s+' 是字母');
}else{
console.log(s+' 不知道是什么');
}
});
编译上诉代码
tsc test.ts
这时会发生编译器会同时帮助我们编译与之相关的其它文件.这就是/// <reference path="xxx" />
这段代码的作用了.它告诉typescript编译器,代码与引用之间的关系.
这时在页面中页用时需要通过四个script
脚本引入编译好的js文件.
当尝试中nodejs中执行node test.js
命令时会得到一个错误,因为我们没有把相关联的文件合并到test.js中,.需要通过下面语句整合三部分到一个文件中,在运行.
tsc --out sample.js test.ts
node sample.js
tsc --out
会自动检查reference
注释关联的代码,并按顺序输出到一个文件中.我们也可以手动指定
tsc --out sample.js validation.ts lettersValidator.ts zipCodeValidator.ts test.ts
在网页中可以通过script
标签<script src="sample.js" type="text/javascript" />
引用.
外部模块
外部模块是与上面相对的,上面所说的不论怎么分文件,最好使用时还是合并成一个文件.像java c#等语言想要引入其它类文件时,都是使用import
进行引入.这种方式在typescript中也是支持的.如nodejs中使用commonjs规范加载模块,js中有amd规范等.
在TypeScript中,只要在顶层代码中上包含有一个export
或import
,都被认为是一个外部模块.
引用一个外部模块将使用var moduleName = import('modulePath')
来代替/// <reference path="xxx" />
标签,
要想编译一个外部模块,在编译时需要加入--module
参数,如:
tsc --module commonjs Test.ts
TypeScript支持导出为’commonjs’,’amd’,’system’,’umd’等模块规范,使用时需时用import
导入模块.
validator.ts
interface StringValidator{
isAcceptable(s:string):boolean;
}
export {StringValidator};
/* //也可以这么导出
export interface StringValidator{
isAcceptable(s:string):boolean;
}
*/
zipCodeValidator.ts
import { StringValidator } from './validator';
export class ZipCodeValidator implements StringValidator{
zipRegexp:RegExp = /^\d{6}$/;
isAcceptable(zip:string){
return this.zipRegexp.test(zip);
}
}
/*
//也可以这么导入
import valid = require('./validator');
export class ZipCodeValidator implements valid.StringValidator{
zipRegexp:RegExp = /^\d{6}$/;
isAcceptable(zip:string){
return this.zipRegexp.test(zip);
}
}
*/
lettersValidator.ts
import { StringValidator } from './validator';
import valid = require('./validator');
export class LettersValidator implements StringValidator{
lettersRegexp:RegExp = /^[a-zA-Z]+$/;
isAcceptable(letters:string){
return this.lettersRegexp.test(letters);
}
}
test.ts
import { ZipCodeValidator } from './zipCodeValidator';
import { LettersValidator } from './lettersValidator';
var str = ['150000', 'hello', '一二三'];
var zipCodeVali = new ZipCodeValidator();
var lettersVali = new LettersValidator();
str.forEach(s=>{
if(zipCodeVali.isAcceptable(s)){
console.log(s+' 是邮政编码');
}else if(lettersVali.isAcceptable(s)){
console.log(s+' 是字母');
}else{
console.log(s+' 不知道是什么');
}
});
tsc --module commonjs test.ts
node test.js