一、接口(interface):對行為和動作的規范,對批量方法進行約束
1.屬性接口
/* 屬性類型接口 */ interface FullName { firstName: string; /* 必傳參數,接口分號間隔 */ secondName?: string; /* 問號表示可選參數,可傳可不傳 */ } function printName(name: FullName) { console.log(name.firstName, name.secondName) /* zhang undefined */ } let obj = { firstName: 'zhang', age: 18 } /* 參數聲明再傳入時,保證必傳參數傳入就不會報錯,比如多傳入age */ printName(obj)
2.函數接口
/* 函數類型接口 */ interface info { (value: string, id: number): string; } let getInfo: info = function (value: string, id: number): string { return value + id /* zhangsan1 */ } console.log(getInfo('zhangsan', 1)) /* zhangsan1 */
3.可索引接口
/* 可索引接口,數組、對象的約束 */ interface infoArr { [index: number]: string /* 對數組的約束 */ } let dataArr: infoArr = ["1", "2"] interface infoObj { [index: string]: string /* 對對象的約束 */ } let dataObj: infoObj = { age: "1", name: "zhangsan" }
4.類類型接口
/* 類類型接口,屬性+函數 */ interface Something { name: string do(value: string): void } class things implements Something { /* implements,實現接口 */ name: string; constructor(name: string) { this.name = name } do() { /* 必須含有name和do() */ console.log(this.name + '玩游戲') /* zhangsan玩游戲 */ } } let s = new things('zhangsan') s.do()
二、接口繼承接口
interface Animal { name: string do(value: string): void } interface Cat extends Animal { /* 接口繼承接口 */ name: string eat(value: string): void } class things implements Cat { /* 實現Cat接口,也必須含有Animal接口的eat方法 */ name: string; constructor(name: string) { this.name = name } do() { console.log('Animal接口的方法') } eat() { console.log('Cat接口的方法') } }
三、泛型:用於解決類接口的復用性,以及解決不特定數據類型的支持
1.什么是泛型?
軟件工程中,我們不僅要創建一致的定義良好的API,同時也要考慮可重用性。 組件不僅能夠支持當前的數據類型,同時也能支持未來的數據類型,這在創建大型系統時為你提供了十分靈活的功能。
在像C#和Java這樣的語言中,可以使用泛型
來創建可重用的組件,一個組件可以支持多種類型的數據。 這樣用戶就可以以自己的數據類型來使用組件。
舉個例子,不用泛型的話,這個函數可能是下面這樣:
function getData1(value:string):string{ return value } function getData2(value:number):number{ return value }
或者,我們使用any
類型來定義函數,但是這也等於放棄了類型檢查:
function getData(value:any):any{ return value }
如果使用泛型的話,可以支持不特定的數據類型,要求就是傳入和返回的類型一致,具體返回什么類型,由調用的時候決定
2.泛型的使用:
添加類型變量T
。 T
幫助我們捕獲用戶傳入的類型(比如:number
),之后我們就可以使用這個類型。 之后我們再次使用了 T
當做返回值類型。現在我們可以知道參數類型與返回值類型是相同的了。 這允許我們跟蹤函數里使用的類型的信息。
2.1泛型函數
function getData<T>(value:T):T{ return value }
2.2泛型類
class Getdata<T>{ list: T[] = []; add(value: T): void { this.list.push(value) } min(): T { var min = this.list[0]; this.list.forEach(function (value) { if (value < min) { min = value; } }); return min; } } let g=new Getdata<number>() g.add(4) g.add(2) g.add(1) g.add(3) console.log(g.min()) // 1
let gd=new Getdata<string>() gd.add('d') gd.add('b') gd.add('a') gd.add('c') console.log(gd.min()) // a
2.3泛型接口
interface Config{ <T>(value:T):T } let getData:Config=function<T>(value:T):T{ return value } console.log(getData('zhangsan')) // zhangsan
我們可能想把泛型參數當作整個接口的一個參數。 這樣我們就能清楚的知道使用的具體是哪個泛型類型(比如:Config<string>而不只是Config
)。 這樣接口里的其它成員也能知道這個參數的類型了。
interface Config<T>{ <T>(value:T):T } // 傳入一個類型參數來指定泛型類型(這里是:string),鎖定了之后代碼里使用的類型。 let getData:Config<string>=function<T>(value:T):T{ return value } console.log(getData('zhangsan')) // zhangsan