使用接口
在前面的筆記中我們知道可以使用Object Type來指定參數的屬性,如下:
1 function printLabel(labelledObj: {label: string}) {
2 console.log(labelledObj.label);
3 }
4
5 var myObj = {size: 10, label: "Size 10 Object"};
6 printLabel(myObj);
這種做法也可以通過接口實現:
1 interface LabelledValue {
2 label: string;
3 }
4
5 function printLabel(labelledObj: LabelledValue) {
6 console.log(labelledObj.label);
7 }
8
9 var myObj = {size: 10, label: "Size 10 Object"};
10 printLabel(myObj);
這里很有意思的一點是,傳遞的參數可以不實現該接口,僅僅帶有接口的屬性即可。
可選屬性
TypeScript的接口還支持可選屬性,這在之前的參數中已經說過,如下:
1 interface SquareConfig {
2 color?: string;
3 width?: number;
4 }
5
6 function createSquare(config: SquareConfig): {color: string; area: number} {
7 var newSquare = {color: "white", area: 100};
8 if (config.color) {
9 newSquare.color = config.collor; // Type-checker can catch the mistyped name here
10 }
11 if (config.width) {
12 newSquare.area = config.width * config.width;
13 }
14 return newSquare;
15 }
16
17 var mySquare = createSquare({color: "black"});
我們傳遞的類型可帶有也可不帶有可選的屬性。
函數類型
這里在之前其實已經說到了,如果你對C#比較熟悉的話,可以將函數類型看做C#中的委托,如下:
1 interface SearchFunc {
2 (source: string, subString: string): boolean;
3 }
4
5 var mySearch: SearchFunc;
6 mySearch = function(source: string, subString: string) {
7 var result = source.search(subString);
8 if (result == -1) {
9 return false;
10 }
11 else {
12 return true;
13 }
14 }
即定義為SerrchFunc類型的函數只能被賦值為在接口中定義好的參數和返回值一致的函數。
數組類型
我們可以通過接口來指定一個存放指定類型的數組:
1 interface StringArray {
2 [index: number]: string;
3 }
4
5 var myArray: StringArray;
6 myArray = ["Bob", "Fred"];
數組類型的寫法是固定的,前面表示索引,返回值表示數組中可以存放的類型,當然其實TypeScript的數組是支持泛型的,所以使用泛型會更加方便一點。
Class類型
終於說到接口最核心的使用方法了,即通過接口來規范類的類型:
1 interface ClockInterface {
2 currentTime: Date;
3 setTime(d: Date);
4 }
5
6 class Clock implements ClockInterface {
7 currentTime: Date;
8 setTime(d: Date) {
9 this.currentTime = d;
10 }
11 constructor(h: number, m: number) { }
12 }
實現接口使用implements關鍵字,同時一個類可以實現多個接口,實現了同一接口的類都可以賦值給該接口類型的變量,這里和Java、C#等語言用法一致。
規范構造函數
這也是TypeScript中比較獨特的地方了,可以通過接口來指定構造函數的參數,我們先看下面的寫法:
1 interface ClockInterface {
2 new (hour: number, minute: number);
3 }
4
5 class Clock implements ClockInterface {
6 currentTime: Date;
7 constructor(h: number, m: number) { }
8 }
這個寫法會報錯,這在TypeScript中是不允許的寫法。
規范構造函數的接口不能使用implemnets實現,而是作為類型存在,如下:
1 interface ClockStatic {
2 new (hour: number, minute: number);
3 }
4
5 class Clock {
6 currentTime: Date;
7 constructor(h: number, m: number) { }
8 }
9
10 var cs: ClockStatic = Clock;
11 var newClock = new cs(7, 30);
這樣的寫法就能達到我們想要的效果了。
接口繼承
接口之間可以繼承,同時支持多重繼承,如下:
1 interface Shape {
2 color: string;
3 }
4
5 interface PenStroke {
6 penWidth: number;
7 }
8
9 interface Square extends Shape, PenStroke {
10 sideLength: number;
11 }
12
13 var square = <Square>{};
14 square.color = "blue";
15 square.sideLength = 10;
16 square.penWidth = 5.0;
這里要注意一下,square並不是實現了該接口的類,所以不能使用new來實現,而是使用<Square>{}的寫法來創建,這里要注意一下。
混合類型
我們可以指定一個對象的類型,如下:
1 interface Counter {
2 (start: number): string;
3 interval: number;
4 reset(): void;
5 }
6
7 var c: Counter;
8 c(10);
9 c.reset();
10 c.interval = 5.0;

