摘要:TypeScript - Interface簡介
TypeScript的一個核心理念就是型別檢查(type-checking),所以提供了Interface
來達成這個目標。就跟C#等物件導向的程式語言一樣,Interface
代表的是程式碼之間的契約(contracts)。也就是說,它為程式碼提供了一個規範,要使用這段程式碼,就需要符合這個規範才能正常使用。設定了Interface,TypeScript的編譯器就可以幫忙檢查型別,以及檢查屬性名稱是否打錯。更好的是,可以支援程式碼編輯器提供Intellisense的功能。
一個簡單的Example
了解Interface
如何運作最快的方式,就是直接看一個簡單的範例
function printLabel(labelledObj: {label: string}) {
console.log(labelledObj.label);
}
var myObj = {size: 10, label: "Size 10 Object"};
printLabel(myObj);
在這個範例中,printLabel()
中只有一個參數,該參數需要傳入一個物件,該物件至少需有一個型別為string
的property-label
。需要注意到的地方是,目前傳進去的物件中,其實除了label
這個property之外,還有其他的property。而TypeScript的Compiler不會要求型別完全一樣,只要物件中有label
這個property就可以了。
這次把Interface的概念加到程式碼中,如下所示:
interface LabelledValue {
label: string;
}
function printLabel(labelledObj: LabelledValue) {
console.log(labelledObj.label);
}
var myObj = {size: 10, label: "Size 10 Object"};
printLabel(myObj);
這裡定義了Interface-LabelledValue
,作為printLabel()
的參數的型別規範。也就是說,呼叫printLabel()
時傳進去的參數,必須符合LabelledValue
的規範。與C#等物件導向語言不一樣的是,符合Interface並不需要實作(Implement),只需要該物件擁有Interface所定義的property及型別就可以了。
Optional Properties
在某些情況下,我們希望Interface中定義的property可以是非強制性的(Optional)。例如以下的例子,createSquare()
需要一個有兩個property-color
& width
的參數物件。而createSquare
想提供預設值的功能,沒有輸入的property,就給他預設值。宣告Optional Properties的方式很簡單,就是在變數名後加個問號?
,例如:color?:string;
interface SquareConfig {
color?: string;
width?: number;
}
function createSquare(config: SquareConfig): {color: string; area: number} {
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"});
Function Types
Interface不但可以用來宣告傳入function的參數型別契約(contracts),還可以用來宣告function本身的契約。也就是宣告function可以允許的傳入參數及傳出的型別。
interface SearchFunc {
(source: string, subString: string): boolean;
}
一旦定義了此Interface,就可以使用類似C#的實作語法 :
,宣告實作此Interface。
var mySearch: SearchFunc;
mySearch = function(source: string, subString: string) {
var result = source.search(subString);
if (result == -1) {
return false;
}
else {
return true;
}
}
宣告function()
用的Interface,好處是可以由編譯器檢查傳入的參數及傳出的型別。在JavaScript的世界中,function是First-class function,可以傳入function當作參數。用到的機會及頻率非常高,因此function的型別檢查非常有用。
First-class function的意義可以參考 JavaScript世界的一等公民- 函數
在很多傳統語言(C/C++/Java/C#等)中,函數都是作為一個二等公民存在,你只能用語言的關鍵字聲明一個函數然後調用它,如果需要把函數作為參數傳給另一個函數,或是賦值給一個本地變量,又或是作為返回值,就需要通過函數指針(function pointer)、代理(delegate)等特殊的方式周折一番。
而在JavaScript世界中函數卻是一等公民,它不僅擁有一切傳統函數的使用方式(聲明和調用),而且可以做到像簡單值一樣賦值、傳參、返回,這樣的函數也稱之為第一級函數(First-class Function)