泛型
軟件工程中,我們不僅要創建一致的定義良好的API,同時要考慮可重用性,組件不僅能夠支撐當前的數據類型,同時也能支持未來的數據類型,這在創建大型項目時為你提供了十分靈活的功能, 像C#和java語言中,可以使用范型創建可重用的組件,一個組件可以支持多種類型的數據,這樣的用戶就可以自己的數據類型來使用組件。通俗來說:泛型就是解決類、接口、方法的復用性、以及不特定數據類型的支持。
泛型的定義和函數
// 只能返回string類型的數據 function getData(value:string):string { return value } // 同時能返回string類型和number類型, 當要返回string類型時使用getData(冗余) function getData1(value:number):number { return value } // ts的其他的方式,實現放回string、number類型 function getData3(value:any):any { return value // 但是有一個問題就是,無法實現類型檢查和約束,你也不知道傳入和返回是否時一致的 } // 我們必須要實現一個方法傳入什么類型,必須返回什么類型,這就可以使用范型了 function getData4<T>(value:T):T{ // 這里的T就是泛型,這里的T不一定時T,也可以是時A、B、C return value } // 使用泛型 alert(getData4<number>(123)) // 約束傳入和返回的類型為number getData4<string>('1111') // 約束傳入和返回的類型為string function getData5<T>(value:T):any{ // 這里的T就是泛型,返回值為any return value } getData5<string>('1111')
demo:比如有個最小堆算法,需要同時支持返回數字和字符串兩種類型,通過類的泛型來實現
class MinClass { public list:number[]=[]; add(num:number){ this.list.push(num); } min():number{ var minNum = this.list[0]; for (var i=0; i<this.list.length;i++){ if (minNum>this.list[i]){ minNum = this.list[i]; } } return minNum } } var m = new MinClass(); m.add(2); m.add(12); m.add(33); m.add(52); alert(m.min()) // 上面的代碼是可以傳入數值返回最小值,那如果我想傳入a-z的字符,能否返回其中最小的 class MinClass1<T> { // 泛型類 public list:T[] = []; add(value:T):void { this.list.push(value) } min():T{ var minNum = this.list[0]; for (var i=0; i<this.list.length;i++){ if (minNum>this.list[i]){ minNum = this.list[i]; } } return minNum } } var m1 = new MinClass1<string>(); // 這里的泛型是string,當然也可以是number m1.add('a'); m1.add('A') m1.add('b') alert(m1.min())
泛型接口
// 函數類型接口 interface ConfigFn { (value1:string,value2:string):string // 函數接口 } var setData:ConfigFn = function(value1:string, value2:string):string{ return value1+value2 } alert(setData('name','wangwu')) // 韓式類型接口實現 // 第一種定義方式:泛型接口 interface ConfigFns { <T>(value1:T):T; // 泛型接口 } var getData:ConfigFns = function<T>(value1:T):T{ return value1 } getData<string>("OK") // 第二種定義方式 interface ConfigFnplus<T> { (value1:T):T; // 泛型接口 } function getData1<T>(value1:T):T{ return value1 } var myGetData:ConfigFnplus<string> = getData1 myGetData("OK,wo")
泛型小demo:
功能: 定義一個操作數據庫的庫,支持Mysql、 Mssql、Mongdb,要求Mysql、Mssql、Mongdb功能一樣,都有add、update、delete、get方法
注意:約束統一規范,以及代碼的重用,解決方案:需要約束規范所以要定義接口,接口是一種規范定義,它定義了行為和動作的規范;泛型通俗理解:泛型就是解決類、接口方法的復用性。
// 定義接口 interface DBI<T>{ add(info:T):boolean; update(info:T,id:number):boolean; delete(id:number):boolean; get(id:number):any[]; } // 實現mongdb類 class MongDb<T> implements DBI<T> { add(info: any): boolean { console.log(info) return true } update(info: any, id: number): boolean { throw new Error("Method not implemented."); } delete(id: number): boolean { throw new Error("Method not implemented."); } get(id: number): any[] { throw new Error("Method not implemented."); } } // 定義一個操作mysql數據庫的類,注意:要實現泛型接口,這個類應該是一個泛型類 class MysqlDb<T> implements DBI<T>{ constructor(){ console.log('數據庫實現連接') } add(info: T): boolean { console.log(info) return true } update(info: T, id: number): boolean { throw new Error("Method not implemented."); } delete(id: number): boolean { throw new Error("Method not implemented."); } get(id: number): any[] { throw new Error("Method not implemented."); } } // 操作用戶表, 定義一個user類和數據表做映射 class User{ username:string|undefined; password:string|undefined; } var u = new User(); u.username='張三'; u.password='123' //var oMysql = new MysqlDb(); // 類作為參數約束數據傳入的類型 var oMysql = new MysqlDb<User>(); // 通過指定類型去校驗參數 oMysql.add(u); // 這里的u是實現了驗證的