總目錄
從C#到TypeScript - 接口
為了更好的抽象出行為和屬性,TypeScript在ES6的基礎(chǔ)上增加了接口interface
。
C#也有interface,不過TypeScript的接口還不大一樣,C#里的接口一般是為類服務(wù),讓類實現(xiàn)接口中定義的方法或?qū)傩浴?br/>TypeScript在C#基礎(chǔ)上更進(jìn)一步,由于JavaScript是門非常靈活的語言,TypeScript作為JavaScript的超集需要保持靈活性,所以接口在TypeScript里可以脫離具體的類,單獨作為類似契約的存在,接口里的屬性也并非一定需要實現(xiàn)。
類的接口
這和C#的差不多,描述了公共的成員;不過實現(xiàn)接口語法有點類似于Java,用的是implements。
interface Selectable { isSelected: boolean; }class Control implements Selectable { isSelected : boolean; }
同C#一樣,接口可以多重繼承其他接口,用的是extends。
interface Editable {}interface Deleteable {}interface Changeable extends Editable, Deleteable {}
接口的屬性
接口的屬性可以定義為readonly
,這個和C#里只有get
沒有set
的屬性有點像,同樣,實現(xiàn)接口的類也不一定需要readonly
。
interface Selectable{ readonly isSelected: boolean; }class Control implements Selectable{ isSelected: boolean; }let s: Selectable = { isSelected : true }; s.isSelected = false; // 編譯出錯, readonlylet c: Control = { isSelected : true }; c.isSelected= false; // 沒問題
另外,接口還支持可選屬性,同C#的可空屬性一樣,用?
表示,實現(xiàn)接口的類可以不用實現(xiàn)可選屬性。
interface RequestConfig { url: string; body?: any; }class Request implements RequestConfig { url: string; }
接口不需要類的支持
在C#里面,接口如果沒有類來實現(xiàn)的話是沒有什么意義的,但在TypeScript里不一樣,接口可以單獨使用。
interface RequestConfig { url: string; body?: any; }let config: RequestConfig = {url: 'www.google.com'};
這種經(jīng)常用在函數(shù)的參數(shù)上面,用來描述具體的參數(shù),把具體的參數(shù)放到接口里,方便操作,也方便重構(gòu)。
function Request(config: RequestConfig){ }
接口除了描述屬性外,還可以用來描述函數(shù),不過一個接口只能描述一個函數(shù),描述時定義好參數(shù)和返回值即可。
從實現(xiàn)上看有點類似于C#的delegate
。
interface CheckLogin { (name: string, pwd: string): boolean; }let check: CheckLogin = function(name: string, pwd: string): boolean { return false; }
另外,接口還可以用來描述可索引類型,就有點類似C#的Dictionary
。
索引支持兩種:number
和string
。
//定義一個Dict,key是string,value也是stringinterface Dict { [key: string] : string; }let dict: Dict = { 'key1': 'value1', 'key2': 'value2'};console.info(dict['key1']); // value1console.info(dict['key']); // undefined
接口繼承類
這在C#中很不可思議,接口居然還可以反過來繼承類,不過對于JavaScript里來說,靈活方便很重要,所以TypeScript實現(xiàn)了這個功能來快速生成一個接口。
雖說在比較復(fù)雜的繼承關(guān)系時可能會有用,不過個人認(rèn)為這個功能還是有點雞肋,因為復(fù)雜的繼承通常會引入一些問題如緊耦合,牽一發(fā)而動全身,再加上這個,可能更讓人摸不著頭腦,不如用組合來得好。
接口繼承類時會繼承類中所有的成員,不管是private
,protected
還是public
,只是不包括其實現(xiàn)。
不過繼承了一個類不公開成員的接口只能被該類或該類的子類實現(xiàn)。
class User{ name: string; protected pwd: string = "123"; }class Admin extends User{ constructor(n: string, p: string){ super(); this.name = n; this.pwd = p; } }interface UserConfig extends User{ //這里包含了name和private的pwd}let config: UserConfig = new Admin('brook', '123');
泛型
TypeScript是同C#一樣支持泛型的,而且在使用方面也差不多,在接口名后面加上<T>
即可。
interface Testable<T> { field: T; (arg: T): T; }
也支持泛型約束,關(guān)鍵字是extends
。
interface Testable<T extends Object> { field: T; (arg: T): T; }
TypeScript的接口對于C#程序員來說是有點奇怪了,不過用過之后還是發(fā)現(xiàn)非常符合JavaScript語言靈活的特性。
http://www.cnblogs.com/brookshi/p/6390073.html