一.TypeScript身世之謎
1.簡介
TypeScript是一種由微軟開發(fā)的自由和開源的編程語言,它是JavaScript的一個超集逸爵,而且本質(zhì)上向這個語言添加了可選的靜態(tài)類型和基于類的面向?qū)ο缶幊炭婚荨0驳滤埂ず査共瘢珻#的首席架構(gòu)師,已工作于TypeScript的開發(fā)拜隧。2012年十月份呻此,微軟發(fā)布了首個公開版本的TypeScript轮纫。
2.特點
TypeScript兼容JavaScript,可以載入JS代碼然后運行焚鲜。JavaScript相比進(jìn)步的地方包括:加入注釋掌唾,讓編譯器理解所支持的對象和函數(shù),編譯器會移除注釋忿磅,不會增加開銷糯彬。 而JavaScript只是一個腳本語言,并非設(shè)計用于開發(fā)大型 Web 應(yīng)用葱她,JavaScript 沒有提供類和模塊的概念撩扒,而TypeScript擴展實現(xiàn)了這些特性。
它擴展了 JavaScript 的語法吨些,因此現(xiàn)有的JavaScript代碼可與其代碼一起工作無需任何修改搓谆,它通過類型注解提供編譯時的靜態(tài)類型檢查。TypeScript可處理已有的JavaScript代碼豪墅,并只對其中的TypeScript代碼進(jìn)行編譯泉手。TypeScript 最大的特點就是類型化,因此才叫做TypeScript偶器。比起弱類型的JavaScript斩萌,類型化的TypeScript顯得更加容易維護(hù)。
3.安裝與使用
(1).通過npm安裝
npm install -g typescript
編譯tsc helloworld.ts
(2).通過編輯器插件
市場上主流的一些前端編輯器都支持ts的插件安裝屏轰,如Visual Studio 2017颊郎,WebStorm,Sublime Text亭枷,Atom等袭艺。
4.上手案例
<script type="text/typescript">
var hw:string="Hello World!"; //定義一個字符串變量
document.write(<h1>"+hw+"</h1>); //將結(jié)果顯示在頁面上,這句話是不是很熟悉呢叨粘。
</script>
如上代碼所示猾编,我們可以把javascript的代碼用到TypeScript里面運行瘤睹。代碼是寫在script標(biāo)簽中,其中的類型是text/typescript答倡。再比如轰传,按照傳統(tǒng)js寫法,定義一個汽車類瘪撇,我們一般會這麼寫:
var Car = (function () {
function Car() {
}
return Car;
})();
var c1 = new Car();
c1.name = "GEELY";
c1.price = 100000;
document.write("name:" + c1.name + " price:" + c1.price);
而使用TypeScript获茬,可以這麼寫:
class Car{
name:string;
price:number;
}
var c1=new Car();
c1.name = "GEELY";
c1.price = 100000;
document.write("name:" + c1.name + " price:" + c1.price);
這樣一來,使用TypeScript代碼更簡潔倔既,更好理解恕曲,更易于維護(hù)。
二.TypeScrip數(shù)據(jù)類型
TypeScript 的基本數(shù)據(jù)類型 有boolean渤涌、number 佩谣、string 、 array 实蓬、 enum 茸俭、any 、void共7種安皱。
1.boolean
最基本的數(shù)據(jù)類型是簡單的真/假值调鬓,其中JavaScript和TypeScript(以及其他語言)稱之為“布爾值”。在JavaScript中變量的定義是通過var關(guān)鍵字來完成酌伊,而在TypeScript中變量的定義格式為:
通過var關(guān)鍵字 變量名后面+冒號 + 數(shù)據(jù)類型來指定,如定義一個boolean的變量:
var isDone: boolean = false;
2.number
用在JS與TS中的所有數(shù)值都是浮點型腾窝,而在TS中我們定義他們?yōu)椤皀umber”型。例如:聲明一個number類型的變量如下代碼:
var isNumber:number=6;
var isfloat:number=6.01;
3.string
string代表字符串腺晾,跟 JavaScript 一樣燕锥,可以使用一對雙引號(")或一對單引號(')來表示字符串辜贵。例如:
var name: string = "bob";
var family_name: string = 'Green';
4.array
TypeScript 中數(shù)組使用“[]”來聲明悯蝉,代碼如下:
var list: number[] = [1, 2, 3];
var name: string[] = ["阿龍","阿貓","阿狗"];
其數(shù)組元素可以通過下標(biāo)去訪問。
var list: number[] = [1, 2, 3];
alert(list[0]));
我們也可以定義任意類型的數(shù)組托慨,關(guān)鍵字為Array.
var arr:Array = [1,2,3,"a","b","c"]; // 任意類型數(shù)組
alert(arr[1]);
5.enum
枚舉類型是 TypeScript 中新添加的鼻由,而 JavaScript 中是沒有這個類型的。用關(guān)鍵字enum來聲明厚棵。代碼示例如下:
enum Color {
Red, //枚舉元素列表
Green,
Blue
};
var c: Color = Color.Green;
跟 C# 一樣蕉世,如果不聲明第一項的值,那么上面 Red 的值就是 0婆硬,然后每一項都增加一狠轻,即 Green 是 1,Blue 是 2彬犯。代碼如下:
enum Color {
Red = 1,
Green,
Blue
};
var c: Color = Color.Green;
所以此時 Red 的值為 1向楼,Green 為 2查吊,Blue 為 3。
當(dāng)然也可以為每一項都指定一個值湖蜕。代碼如下:
enum Color {
Red = 1,
Green = 2,
Blue = 4
};
var c: Color = Color.Green;
另外枚舉類型還有一個比較特殊的功能逻卖,假如我們有一個數(shù)值,但是我們不知道枚舉類型中是否有定義昭抒,可以用以下方式來獲取评也,代碼如下:
enum Color {
Red = 1,
Green,
Blue
};
var colorName: string = Color[2]; //訪問第二個枚舉子元素Green
alert(colorName);
colorName = Color[4];
alert(colorName);
那么將會輸出Green和undefined。因為Green的值是 2灭返,而沒有一個枚舉定義的值是 4盗迟,所以返回undefined。
6.any
和 JavaScript 中變量的默認(rèn)類型一樣熙含,指代是動態(tài)的诈乒,能夠賦予任意類型。例如:
var notSure: any = 4;
notSure = "maybe a string instead";
notSure = false; // 定義為boolen型
定義為any后婆芦,將失去語法感知的功能怕磨,就相當(dāng)于寫JavaScript 一樣。
值得一提的是消约,any可以配合數(shù)組來使用肠鲫,代碼如下:
var list: any[] = [1, true, "free"];
list[1] = 100; //更改list[1]的值
7.void
這個類型僅能在函數(shù)中使用,可以將函數(shù)的返回類型指定為 void或粮,表示該函數(shù)不返回任何值导饲。代碼如下:
function warnUser(): void {
alert("This is my warning message");
}
三.TypeScript函數(shù)
1.函數(shù)的定義與調(diào)用
在TypeScript中定義函數(shù)的語法為:
function functionName(arg:number,arg1:number,....):return_type{
code 函數(shù)要執(zhí)行的代碼;
return data;
}
其中 function 為聲明函數(shù)的關(guān)鍵字,functionName 為自定義函數(shù)的名字氯材,arg為參數(shù)列表渣锦,return_type為該函數(shù)的返回值類型,code為函數(shù)被調(diào)用時要執(zhí)行的代碼氢哮,使用return關(guān)鍵字返回數(shù)據(jù)袋毙,data為要返回的數(shù)據(jù),要使用“{}”括起來冗尤。栗子如下代碼所示:
function add(x: number, y: number): number { //定義返回值為number類型的函數(shù)
return x+y;
}
add(5,6); //調(diào)用函數(shù)
當(dāng)然也可以沒有返回值听盖。
2.匿名函數(shù)
匿名函數(shù)是沒有名稱只有主體的函數(shù),不需要指定返回類型裂七,它的返回值類型是從函數(shù)主體內(nèi)的 return 語句推斷的皆看。如下代碼:
var myAdd = function(x:number, y:number) { //定義匿名函數(shù)
return x+y;
};
myAdd(3,4); //調(diào)用匿名函數(shù)
3.可選與默認(rèn)參數(shù)
可選參數(shù):在參數(shù)名后面,冒號前面添加一個問號背零,則表明該參數(shù)是可選的腰吟。如下代碼:
function buildName(firstName: string, lastName?: string) { //lastName為可選參數(shù)
if (lastName)
return firstName + " " + lastName;
else
return firstName;
}
var result1 = buildName("Bob"); //正確調(diào)用 Bob
var result2 = buildName("Bob", "Adams"); //正確調(diào)用 Bob Adams
默認(rèn)參數(shù):在參數(shù)名后直接給定一個值,如果這個值沒有被傳入徙瓶,那么將會被賦值為默認(rèn)值毛雇。如下代碼:
function buildName(firstName: string, lastName = "Smith") {
return firstName + " " + lastName;
}
var result1 = buildName("Bob"); //沒有傳入第二個參數(shù)录语,則被賦值為默認(rèn)的smith,結(jié)果為:Bob Smith
var result2 = buildName("Bob", "Adams"); //結(jié)果為:Bob Adams
注:可選參數(shù)和默認(rèn)參數(shù)必須在參數(shù)列表的最后。
三.TypeScript類
1.類的結(jié)構(gòu)及聲明
JavaScript語言基于函數(shù)和原型鏈繼承機制的方式構(gòu)建可重用的組件禾乘。這對于面向?qū)ο缶幊虂碚f顯得比較笨拙澎埠。在下一代的JavaScript標(biāo)準(zhǔn)將為我們提供基于class base的面向?qū)ο蟮脑O(shè)計方式。但在TypeScript中可以使用這種方式始藕,它將編譯為目前大多數(shù)瀏覽器能允許的普通JavaScript代碼蒲稳,所以我們不用在等下一代Javascript標(biāo)準(zhǔn)的到來了。
類是面向?qū)ο缶幊痰暮诵幕A(chǔ)伍派,是屬性和方法的集合江耀,類不能真接編寫程序時引用,必須實例化后才能使用诉植。
創(chuàng)建一個TypeScript類時祥国,必須使用關(guān)鍵字class進(jìn)行聲明,該關(guān)鍵字后緊跟類的名稱晾腔,之后用大括號將類體進(jìn)行封裝舌稀,類的基本聲明格式如下。
class 類名{
//類體
}
創(chuàng)建完成類的基本結(jié)構(gòu)后就可以編寫類體灼擂。類體中主要包括屬性和方法的聲明及定義壁查,當(dāng)然也可能在類體中只定義屬性或只定義方法,甚至類體內(nèi)可以不定義任何屬性剔应。完整的類的定義格式如下睡腿。
class 類名{
name:string; //定義類的屬性
fun(){ //定義類的方法
//定義該方法所要實現(xiàn)的功能
}
}
2.屬性和方法的定義
通過以上介紹,已經(jīng)可以對類的屬性和方法有所了解峻贮,下面具體介紹類體內(nèi)屬性和方法的定義和使用席怪。
(1)屬性:類的屬性實質(zhì)為在類體內(nèi)定義的變量,用于保存或設(shè)置參數(shù)纤控。
(2)方法:類的方法實質(zhì)為在類體內(nèi)定義的函數(shù)挂捻,用于實現(xiàn)某項功能,其定義方法與普通函數(shù)定義方法相同嚼黔,同時可以應(yīng)用訪問權(quán)限關(guān)鍵字對方法訪問權(quán)限進(jìn)行限制细层。
class 類名{
name:string; //定義類的屬性
fun(){ //定義了一個無返回值的方法
//定義該方法所要實現(xiàn)的功能
}
say():string{ //定義返回值類型為string的方法
//定義該方法所要實現(xiàn)的功能
return "返回值"; // 用return關(guān)鍵字返回函數(shù)值
}
}
3.靜態(tài)屬性
TypeScript可以使用“static” 關(guān)鍵字標(biāo)注類的成員。如下代碼:
class calc{
static count=10;
add(data1:number):number{
var sum=calc.count+data1;
return sum;
}
}
var test=new calc();
document.write(test.add(20));
類成員的靜態(tài)屬性我們可以直接調(diào)用唬涧,調(diào)用方式為如上例的count的調(diào)用方式:calc.count。而不能用this.count在類的內(nèi)部使用盛撑。
4.構(gòu)造函數(shù)
構(gòu)造函數(shù) 碎节,是一種特殊的方法。主要用來在創(chuàng)建對象時初始化對象抵卫, 即為對象成員變量賦初始值狮荔,總與new運算符一起使用在創(chuàng)建對象的語句中胎撇。而TypeScript的構(gòu)造函數(shù)用關(guān)鍵字constructor來實現(xiàn)≈呈希可以通過this(和java/C#一樣代表對象實例的成員訪問)關(guān)鍵字來訪問當(dāng)前類體中的屬性和方法晚树。
class student{ //定義student類
name:string; //定義類的屬性
constructor(myname:string){ //定義構(gòu)造函數(shù)
this.name=myname;
}
study(){ //定義類的方法
//定義該方法所要實現(xiàn)的功能
}
}
5.類的實例化
一般情況下,創(chuàng)建一個類后并不能直接的對屬性和方法進(jìn)行引用雅采,必須對類進(jìn)行實例化爵憎,即創(chuàng)建一個對象。TypeScript中用new 關(guān)鍵字創(chuàng)建對象婚瓜。實例化后通過“.”來訪問屬性和方法宝鼓。實例代碼如下:
class student{ //定義student類
name:string; //定義類的屬性
constructor(myname:string){ //定義帶參數(shù)的構(gòu)造函數(shù)
this.name=myname;
}
study(){ //定義類的方法
document.write("<h1> My name is "+this.name+".</h1>");
}
write():string{
return "write name:"+this.name;
}
}
var s1=new student("Jim");
document.write("<h1>"+s1.name+"</h1>"); //獲取name屬性
s1.study(); // 調(diào)用study方法
document.write("<h1>"+s1.write()+"</h1>");
6.繼承
TypeScript中用關(guān)鍵字extends指明繼承關(guān)系。例如巴刻,已經(jīng)定義了類A愚铡,如果讓類B繼承A,我們把A叫做基類,B叫子類胡陪×ち龋可以用下面的方式定義類B。
class B extends A {
// 類B中的成員
}
如果我們要在子類中調(diào)用基類中的屬性與方法就要使用super關(guān)鍵字柠座。如下代碼:
class Animal { //定義基類
name:string;
constructor(theName: string) { this.name = theName; }
move(meters: number) {
document.write(this.name + " moved " + meters + "m.");
}
}
class Snake extends Animal { //繼承基類
constructor(name: string) {
super(name); //調(diào)用基本類的構(gòu)造函數(shù)
}
move() { //重寫了基類的方法
document.write("Slithering...<br>");
super.move(5); //調(diào)用基類的方法
}
}
var sam = new Snake("Python"); //聲明Snake類
sam.move();
在TypeScript中我們采用“extends”關(guān)鍵字來表示類的繼承關(guān)系营曼。在這里你可以看見“Snake”繼承“Animal”的子類實現(xiàn)。在實例中也展示如何去重寫父類的方法愚隧,在這里“Snake”創(chuàng)建了一個“move”方法來重寫父類“Animal”的“move”方法蒂阱,并通過“super”關(guān)鍵字來調(diào)用父類的方法。
四.TypeScript接口
1.接口聲明
在TypeScript中狂塘,接口是用作約束作用的录煤,在編譯成JavaScript的時候,所有的接口都會被擦除掉荞胡,因為 JavaScript中并沒有接口這一概念妈踊。TypeScript中接口是用關(guān)鍵字interface進(jìn)行聲明,例如:
interface LabelledValue { //定義接口
label: string;
}
function printLabel(labelledObj: LabelledValue) { //定義函數(shù)printLabel,其參數(shù)類型為接口類型
document.write(labelledObj.label);
}
var myObj = {size: 10, label: "Size 10 Object"}; //定義含有接口中屬性的對象
printLabel(myObj); //調(diào)用函數(shù)
在上面的例子中泪漂,printLabel函數(shù)要求傳入一個包含一個label的字符串屬性廊营。而接口LabelledValue描述了printLabel的所要求的類型對象。它依然代表包含一個label的字符串屬性萝勤。
2.可選屬性
有時不是所有定義在interface中的屬性都是必須的露筒,typescript中便為我們提供了可選屬性。帶有可選屬性的interface定義和c#語言很相似敌卓,以?緊跟變量名后邊表示慎式。如下代碼:
interface SquareConfig { //定義了兩個可選屬性
color?: string;
width?: number;
}
function createSquare(config: SquareConfig): {color: string; area: number} {//定義函數(shù)
var newSquare = {color: "white", area: 100};
if (config.color) {
newSquare.color = config.color;
}
if (config.width) {
newSquare.area = config.width * config.width;
}
return newSquare;
}
var mySquare = createSquare({color: "black"}); //調(diào)用函數(shù),
document.write(mySquare.color); //結(jié)果為: black
既然是可選屬性,那么為什么還要定義呢?對比起完全不定義瘪吏,定義可選屬性主要是:如果存在屬性癣防,能約束類型。
3.方法類型
在 JavaScript 中掌眠,方法 function 是一種基本類型蕾盯。在面向?qū)ο笏枷胫校涌诘膶崿F(xiàn)是靠類來完成的蓝丙,而 function 作為一種類型级遭,是不是能夠?qū)崿F(xiàn)接口呢?是的,在 TypeScript 中迅腔,我們可以使用接口來約束方法的簽名装畅。
interface SearchFunc {
(source: string, subString: string): boolean; //定義一個匿名方法
}
var mySearch: SearchFunc;
mySearch = function(source: string, subString: string) { //實現(xiàn)接口
var result = source.search(subString); //調(diào)用系統(tǒng)方法search查找字符串的位置
if (result == -1) {
return false;
}
else {
return true;
}
}
上面代碼中,我們定義了一個接口沧烈,接口內(nèi)約束了一個方法的簽名掠兄,這個方法有兩個字符串參數(shù),返回布爾值锌雀。在第二段代碼中我們聲明了這個接口的實現(xiàn)蚂夕。編譯器僅僅檢查類型是否正確(參數(shù)類型、返回值類型)腋逆,因此參數(shù)的名字我們可以換成別的婿牍。
4.數(shù)組類型
在數(shù)組類型中有一個“index”類型其描述數(shù)組下標(biāo)的類型,以及返回值類型描述每項的類型惩歉。如下:
interface StringArray { //定義數(shù)組接口
[index: number]: string; //每個數(shù)組元素的類型
}
var myArray: StringArray;
myArray = ["Bob", "Fred"];
在接口的定義里面等脂,索引器的名字一般為 index(當(dāng)然也可以改成別的,但一般情況下都是保持名字為 index)撑蚌。索引器的類型只能為 number 或者 string上遥。
interface Array{
[myindex: number]: number;
}
interface Dictionary{
[index: string]: any;
}
5.Class類型
在C#和java中interface是很常使用的類型系統(tǒng),其用來強制其實現(xiàn)類符合其契約争涌。在TypeScript中同樣也可以實現(xiàn)粉楚,通過類實現(xiàn)接口要用implements關(guān)鍵字。如下代碼:
interface IPrint{
print();
}
class A implements IPrint { //實現(xiàn)接口
print(){ //實現(xiàn)接口中的方法
document.write("實現(xiàn)接口");
}
}
var B=new A();
B.print();
6.接口繼承
和類一樣亮垫,接口也能繼承其他的接口模软。這相當(dāng)于復(fù)制接口的所有成員。接口也是用關(guān)鍵字“extends”來繼承饮潦。
interface Shape { //定義接口Shape
color: string;
}
interface Square extends Shape { //繼承接口Shape
sideLength: number;
}
一個interface可以同時繼承多個interface燃异,實現(xiàn)多個接口成員的合并。用逗號隔開要繼承的接口害晦。
interface Shape {
color: string;
}
interface PenStroke {
penWidth: number;
}
interface Square extends Shape, PenStroke {
sideLength: number;
}
需要注意的是特铝,盡管支持繼承多個接口暑中,但是如果繼承的接口中壹瘟,定義的同名屬性的類型不同的話鲫剿,是不能編譯通過的。如下代碼:
interface Shape {
color: string;
test: number;
}
interface PenStroke extends Shape{
penWidth: number;
test: string;
}
五.TypeScript接口模塊
前端數(shù)據(jù)驗證在改善用戶體驗上有很大作用,使用文章之前介紹的一些方法稻轨,可以這麼寫:
interface StringValidator { //定義驗證接口
isAcceptable(s: string): boolean;
}
var lettersRegexp = /^[A-Za-z]+$/;
var numberRegexp = /^[0-9]+$/;
class LettersOnlyValidator implements StringValidator { //實現(xiàn)接口
isAcceptable(s: string) {
return lettersRegexp.test(s);
}
}
class ZipCodeValidator implements StringValidator { //實現(xiàn)接口
isAcceptable(s: string) {
return s.length === 5 && numberRegexp.test(s);
}
}
var strings = ['Hello', '98052', '101'];
var validators: { [s: string]: StringValidator; } = {};
validators['ZIP code'] = new ZipCodeValidator(); //實例化類
validators['Letters only'] = new LettersOnlyValidator(); //實例化類
for(var i=0;i<strings.length;i++){
for (var name in validators) {
document.write('"' + strings[i] + '" ' + (validators[name].isAcceptable(strings[i]) ? ' matches ' : ' does not match ') + name+"<br>"); //調(diào)用類的方法
}
}
那么這段代碼最大的問題是什么呢灵莲?一個是沒法復(fù)用,驗證的封裝和驗證過程在同一個文件殴俱,驗證的封裝已經(jīng)是可以復(fù)用的政冻。另一個是接口和兩個實現(xiàn)的類都直接掛接在全局變量上,假如數(shù)量一多的話线欲,將會影響整個全局變量明场。
而TypeScritp中模塊的出現(xiàn)給我們解決了這一問題。使用 module 關(guān)鍵字來定義模塊李丰,并在末尾加花括號即可用苦锨; 用export 關(guān)鍵字使接口、類等成員對模塊外可見趴泌。
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);
}
}
}
2,模塊內(nèi)容的調(diào)用
在模塊聲明完成以后舟舒,我們就可以調(diào)用這個模塊了,調(diào)用模塊中的接口嗜憔、類秃励、方法等。調(diào)用方法簡單吉捶,就是用模塊名后面跟一個點來調(diào)用類夺鲜、接口、方法等呐舔。如下代碼:
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);
}
}
}
var strings = ['Hello', '98052', '101'];
var validators: { [s: string]: Validation.StringValidator; } = {};
validators['ZIP code'] = new Validation.ZipCodeValidator(); //使用模塊中的類
validators['Letters only'] = new Validation.LettersOnlyValidator();
// 顯示匹配結(jié)果
for(var i=0;i<strings.length;i++){
for (var name in validators) {
document.write('"' + strings[i] + '" ' + (validators[name].isAcceptable(strings[i]) ? ' matches ' : ' does not match ') + name+"<br>"); // 使用方法
}
}
3.分隔模塊到多個文件
隨著項目的擴展币励,代碼總不可能只寫在一個文件里。為了更好地維護(hù)項目滋早,最好將特定功能放到一個文件里榄审,然后加載多個文件實現(xiàn)我們想需要的功能。現(xiàn)在先將上面的代碼分割到多個文件里杆麸。
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" />
var strings = ['Hello', '98052', '101'];
var validators: { [s: string]: Validation.StringValidator; } = {};
validators['ZIP code'] = new Validation.ZipCodeValidator();
validators['Letters only'] = new Validation.LettersOnlyValidator();
for(var i=0;i<strings.length;i++){
for (var name in validators) {
document.write('"' + strings[i] + '" ' + (validators[name].isAcceptable(strings[i]) ? ' matches ' : ' does not match ') + name+"<br>"); //調(diào)用類的方法
}
}
在項目中新建好以上四個文件搁进,然后我們編譯項目,如果我們代碼編寫沒錯的話昔头,是能夠編譯通過的饼问。另外,我們可以見到后面三個文件開頭有類似于 C# 的文檔注釋揭斧,這是告訴 TypeScript 編譯器該文件依賴于哪些文件莱革,假如依賴的文件不存在的話峻堰,編譯就會不通過。當(dāng)然我們不寫也是可以的盅视,只不過編譯器在編譯時不會幫我們檢查捐名,一般來說,還是建議寫上闹击。 另外镶蹋,在引用編譯生成的 JavaScript 文件時,我們需要注意好順序赏半。以上面的代碼為例贺归,我們在 Html 代碼中已經(jīng)這么引用。
<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"/>