[TypeScript]Interface簡介

  • 1769
  • 0
  • 2016-03-05

摘要: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()中只有一個參數,該參數需要傳入一個物件,該物件至少需有一個型別為stringproperty-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)


參考