typescript - 6.泛型

泛型函数的声明方式

// 普通函数
function info(name : string, age : number) : string {
    return name + '的年龄为:' + age
}
// 匿名函数
let info = function (name : string, age : number) : string {
  return name + '的年龄为:' + age
}
// 匿名函数 2
let info : (name : string, age : number) => string = function (name, age) {
  return name + '的年龄为:' + age
}

PS:匿名函数 2 的声明方式中的“=>”箭头函数,表示函数的返回类型;

那么用泛型来表示上面的匿名函数,我们可以对照的样式来写;

function info<T>(msg : T) : T {
return msg
}
// 匿名函数形式的泛型类型
let myInfo : <T>(msg : T) => T = function (msg) {
return msg
}

PS:变形到这里,你会发现 : <T>(msg : T)这个就是类型了,即:泛型类型

我们也可以以对象类型的调用签名的形式,书写这个泛型类型:

let myInfo2 : {<T>(msg : T) : T} = function (msg) {
return msg
}

泛型接口的演变

泛型不但可以作为类型来使用,还可以继续变形,用对象字面量的形式存在;和上面签名形式一样

// 对象字面量形式的泛型类型
let myInfo2 : {<T>(msg : T) : T} = function (msg) {
return msg
}

PS:如果用{}对象字面量方式,那么=>箭头函数就改成:冒号的对应语法即可;
2. 继续变形,泛型类型支持{},那么就可以使用接口方式进行分离,有助于复用;

// 将对象字面量形式用接口形式代替
interface Iinfo {
<T>(msg : T) : T
}
let myInfo : Iinfo = function (msg) {
return msg
}
console.log(myInfo<string>('Mr.Lee'))

PS:当然,还可以变形,就是将的类型参数通过 Iinfo这样传递;

interface Iinfo<T> {
(msg : T) : T
}
let myInfo : Iinfo<string> = function (msg) {
return msg
}
console.log(myInfo('Mr.Lee')

泛型类

class MinClas<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 MinClas<number>();   /*实例化类 并且制定了类的T代表的类型是number*/
m1.add(11);
m1.add(3);
m1.add(2);
alert(m1.min())


var m2=new MinClas<string>();   /*实例化类 并且制定了类的T代表的类型是string*/

m2.add('c');
m2.add('a');
m2.add('v');
alert(m2.min())

泛型接口

一个普通函数类接口

  interface ConfigFn{
            (value1:string,value2:string):string;
        }


        var setData:ConfigFn=function(value1:string,value2:string):string{


            return value1+value2;
        }

        setData('name','张三');

泛型接口第一种:

interface ConfigFn {
    <T>(value: T): T;
}

var getData: ConfigFn = function <T>(value: T): T {

    return value;
}

getData<string>('张三');

getData<string>(1243);  //错误

来看第二种写法:

interface ConfigFn<T>{
    (value:T):T;
}

function getData<T>(value:T):T{
    return value;
}

//也可以写匿名函数的
//let myGetData:ConfigFn<string>=function <T>(value:T):T{
//    return value;
//};   

let myGetData:ConfigFn<string>=getData;     

myGetData('20');  /*正确*/

// myGetData(20)  //错误

//可以这样写
let myGetData2: <T>(arg: T) =>  T  = getData;

let output =  myGetData2('220');  /*正确*/

赋值还有两种写法

let myGetData2: <T>(arg: T) =>  T  = getData;
let myGetData3: {<T>(value:T):T}  = getData;

泛型类

//定义操作数据库的泛型类
class MysqlDb<T>{
    add(info:T):boolean{
        console.log(info);       
        return true;
    }
    updated(info:T,id:number):boolean {
        console.log(info);  
        
        console.log(id); 

        return true;
    }
}


//想给User表增加数据

// 1、定义一个User类 和数据库进行映射

// class User{
//     username:string | undefined;
//     pasword:string | undefined;
// }
// var u=new User();
// u.username='张三';
// u.pasword='123456';
// var Db=new MysqlDb<User>();
// Db.add(u);



//2、相关ArticleCate增加数据  定义一个ArticleCate类 和数据库进行映射


class ArticleCate{
    title:string | undefined;
    desc:string | undefined;
    status:number | undefined;
    constructor(params:{
        title:string | undefined,
        desc:string | undefined,
        status?:number | undefined
    }){

        this.title=params.title;
        this.desc=params.desc;
        this.status=params.status;


    }
}
//增加操作
// var a=new ArticleCate({
//     title:'分类',
//     desc:'1111',
//     status:1
// });

// //类当做参数的泛型类
// var Db=new MysqlDb<ArticleCate>();
// Db.add(a);

//修改数据
var a=new ArticleCate({
        title:'分类111',
        desc:'2222'      
});

a.status=0;
var Db=new MysqlDb<ArticleCate>();
Db.updated(a,12);
posted @ 2019-05-08 21:40  【唐】三三  阅读(244)  评论(0编辑  收藏  举报