Typescript(十三)泛型

作者: camellias__ | 来源:发表于2021-06-15 16:40 被阅读0次

    泛型:[generic - 通用、泛指的意思],那最简单的理解,泛型就是泛指的类型。

    一:函数中的泛型

    1:定义一个泛型方法

    // 泛型
    function query<T>(param:T)
    {
        console.log(typeof param);
        console.log(param);
    }
    query<string>('sucess');
    // 输出:
    // string
    // sucess
    

    从上边的代码我们就可以看出,其实泛型这个很容易理解,就是我们在调用方法的时候传参可能不知道要传递何种类型,那么我们就在调用函数的时候传递参数类型。

    2:泛型中数组的使用

    如果传递过来的值要求是数字,如何用泛型进行定义那?两种方法,第一种是直接使用[],第二种是使用Array<泛型>。形式不一样,其他的都一样。

    代码如下:

    function query1<T>(param:Array<T>)
    {
        console.log(typeof param);
        console.log(param);
    }
    function query2<T>(param:T[])
    {
        console.log(typeof param);
        console.log(param);
    }
    query1<string>(['sucess','error']);
    // 输出:
    // object
    // [ 'sucess', 'error' ]
    

    3:多个泛型的定义

    一个函数只能定义一个泛型吗?当然不是,是可以定义多个的,这里还是拿join方法举例,定义多个泛型,比如第一个泛型用T,第二个用P代表。

    代码如下:

    function join<T, P>(first: T, second: P) 
    {
      console.log(`${first}${second}`);
    }
    join < number, string > (1, "2");
    // 输出:12
     
    

    4:类型推断

    泛型也是支持类型推断的,比如下面的代码并没有报错,这就是类型推断的功劳。

    function join<T, P>(first: T, second: P) {
      return `${first}${second}`;
    }
    join(1, "2");
    

    但个人不建议大量使用类型推断,这会让你的代码易读和健壮性都会下降

    所以这个知识点,大家做一个了解就可以了。

    二:类中的泛型

    1:首先我们定义一个泛型类:

    class selectGirl <T>{
        // 声明一个私有变量数组
        public lists:Array<T>;
        // 构造函数
        constructor(param:Array<T>)
        {
            this.lists = param;
            console.log(this.lists);
        }
    }
    

    调用一下:

    let ass = new selectGirl<string>([
        "大脚", "刘英","小蒙"
    ]);
    // 输出:[ '大脚', '刘英', '小蒙' ]
    

    这个就是在类中对泛型最简单的使用。

    2:泛型的继承

    现在我们需要获取这个女孩子的名字,我们定义了一个新方法getName

    class selectGirl <T>{
        // 声明一个私有变量数组
        public lists:Array<T>;
        // 构造函数
        constructor(param:Array<T>)
        {
            this.lists = param;
            console.log(this.lists);
        }
        /**
         * 获取名字
         */
        public getName(num:number):string
        {
            let asd = this.lists[num];
            return asd;
          // 这样写会报错,不能将类型“T”分配给类型“string”。
        }
    }
     
    let ass = new selectGirl<string>([
        "大脚", "刘英","小蒙"
    ]);
    let res = ass.getName(1);
    

    这样写会报错,不能将类型“T”分配给类型“string”。

    就是我们没有办法指定泛型中的值为string。

    解决方法就使用到泛型的继承,代码如下:

    interface girl{
        name:string
    }
    class selectGirl <T extends girl>{
        // 声明一个私有变量数组
        public lists:Array<T>;
        // 构造函数
        constructor(param:Array<T>)
        {
            this.lists = param;
            console.log(this.lists);
        }
        /**
         * 获取名字
         */
        public getName(num:number):string
        {
            let asd = this.lists[num].name;
            return asd;
        }
    }
     
    let result = new selectGirl<girl>([
        {name:"大脚"}, 
        {name:"刘英"},
        {name: "小蒙"}
    ]);
     
    let res = result.getName(1);
    console.log(res);
    // 输出:
    //[ { name: '大脚' }, { name: '刘英' }, { name: '小蒙' } ]
    // 刘英
    

    三:泛型的约束

    泛型的约束还是使用到extends关键字,我们还是使用到上边的代码。不使用继承,改成使用泛型的约束来实现上边的功能。

    class selectGirl <T extends string | number>{
        // 声明一个私有变量数组
        public lists:Array<T>;
        // 构造函数
        constructor(param:Array<T>)
        {
            this.lists = param;
            console.log(this.lists);
        }
        /**
         * 获取名字
         */
        public getName(num:number):T
        {
            return this.lists[num];
        }
    }
     
    let result = new selectGirl<string>([
         '大脚', '刘英', '小蒙' 
    ]);
     
    let res = result.getName(1);
    console.log(res);
    // 输出:
    // [ '大脚', '刘英', '小蒙' ]
    // 刘英
    

    以上大概就是泛型的基础知识。

    有好的建议,请在下方输入你的评论。

    欢迎访问个人博客
    https://guanchao.site

    相关文章

      网友评论

        本文标题:Typescript(十三)泛型

        本文链接:https://www.haomeiwen.com/subject/euwzeltx.html