TypeScript_泛型

typescript 中很多地方都和 java 和 C# 相似,如果 有 java 和 C# 的同学入手typeScript 会简单很多,

下面这里使用代码来表示和展现泛型的定义和使用

//泛型:在类、接口、函数中对不确定(未知)的数据类型的支持,提高 类、接口、函数代码的复用性,减少冗余
//开发人员可以根据不同的数据类型使用同一个接口、函数或者类


/**
 *  以下例子
 *  定一个获取最小值的函数,当获对应的集合为 数字 时,需编写一个 针对数字集合 获取最小值的函数,
 *  当集合为 字符串 时,则需另外定义一个针对字符串集合获取最小值得函数,
 *  这时就会会造成代码的冗余,代码复用性低
 *  如下:
 */
function min1(list:number[]):number{
    let minRes:number = list[0];
    list.forEach((item, index)=>{
        if(item < minRes){
            minRes = item;
        }
    });
    return minRes;
}

function min2(list:string[]):string{
    let minRes:string = list[0];
    list.forEach((item, index)=>{
        if(item < minRes){
            minRes = item;
        }
    });
    return minRes;
}

console.log(min1([9,3,4,2,5])); // 输出   2
console.log(min2(['r','a','c','b','h','f'])); // 输出   a

/**
 * 使用泛型则可以解决以上问题
 * 传入和返回的数据类型由函数调用者自己来决定, 无需多写冗余的代码
 *  T 代表未知类型, 也可用用其他自定义单词或者字母表示
 */
function min<T>(list:T[]):T {
    let minRes:T = list[0];
    list.forEach((item, index)=>{
        if(item < minRes){
            minRes = item;
        }
    });
    return minRes;
}

console.log(min1([9,3,4,2,5])); // 输出   2
console.log(min2(['r','a','c','b','h','f'])); // 输出   a


/**
 * 泛型类
 */
class Operation<T>{
    list:T[] = [];
    constructor(){}

    add(v:T):void{
        this.list.push(v);
    }

    getList():T[]{
        return this.list;
    }

    min():T{
        let minRes:T = this.list[0];
        this.list.forEach((item, index)=>{
            if(item < minRes){
                minRes = item;
            }
        });
        return minRes;
    }
}

//指定类型为number类型
let o = new Operation<number>(); //实例化类,并指定了类中 T 代表的是 number类型
//o.add('e'); //报错,必须为number类型
o.add(6);
o.add(4);
o.add(8);
o.add(7);
console.log(o.getList()); // 输出: [6, 4, 8, 7]
console.log(o.min());   //输出: 4

let o1 = new Operation<string>();  //实例化类,并指定了类中 T 代表的是 string类型
// o1.add(6);  //报错,必须为字符串类型
o1.add('e');
o1.add('n');
o1.add('b');
o1.add('l');
console.log(o1.getList()); // 输出:  ["e", "n", "b", "l"]
console.log(o1.min());   //输出: b


/**
 * 泛型接口
 */
interface Z<T> {
    value:T;
    getValue():T;
}

//第一种: 直接在类中定义指定类型
class A implements Z<string> {
    value:string;
    constructor(name:string){
        this.value = name;
    }
    getValue(): string {
        return this.value;
    }
}

//实例化类时,传入指定类型
let a = new A('aaa');
alert(a.getValue())

//第二种:在类中指定任意类型
class B<Q> implements Z<Q> {
    value :Q;
    constructor(name:Q){
        this.value = name;
    }
    getValue(): Q {
        return this.value;
    }
}

//实例化类时,可指定任意的类型
let b = new B<number>(1111);
alert(b.getValue());

let b1 = new B<string>('b1b1b1');
alert(b1.getValue())