泛型
軟件工程中,我們不僅要創建一致的定義良好的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是實現了驗證的
