TS泛型

88 阅读1分钟

泛型

有时,书写某个函数时,会丢失一些类型信息(多个位置的类型应该保持一致或有关联的信息)

泛型:是指附属于函数、类、接口、类型别名之上的类型

泛型相当于是一个类型变量,在定义时,无法预先知道具体的类型,可以用该变量来代替,只有到调用时,才能确定它的类型

很多时候,TS会智能的根据传递的参数,推导出泛型的具体类型

如果无法完成推导,并且又没有传递具体的类型,默认为空对象

泛型可以设置默认值

在函数中使用泛型

在函数名之后写上<泛型名称>

interface hasNameProperty {
    name: string
}

/**
 * 将某个对象的name属性的每个单词的首字母大小,然后将该对象返回
 */
function nameToUpperCase<T extends hasNameProperty>(obj: T): T {
    obj.name = obj.name
        .split(" ")
        .map(s => s[0].toUpperCase() + s.substr(1))
        .join(" ");
    return obj;
}

如何在类型别名、接口、类中使用泛型

直接在名称后写上<泛型名称>

在类中使用泛型:

export class ArrayHelper<T> {

    constructor(private arr: T[]) { }

    take(n: number): T[] {
        if (n >= this.arr.length) {
            return this.arr;
        }
        const newArr: T[] = [];
        for (let i = 0; i < n; i++) {
            newArr.push(this.arr[i]);
        }
        return newArr;
    }


    shuffle() {
        for (let i = 0; i < this.arr.length; i++) {
            const targetIndex = this.getRandom(0, this.arr.length);
            const temp = this.arr[i];
            this.arr[i] = this.arr[targetIndex];
            this.arr[targetIndex] = temp;
        }
    }


    private getRandom(min: number, max: number) {
        const dec = max - min;
        return Math.floor(Math.random() * dec + max);
    }
}

泛型约束

泛型约束,用于现实泛型的取值

多泛型

//将两个数组进行混合
//[1,3,4] + ["a","b","c"] = [1, "a", 3, "b", 4, "c"]
function mixinArray<T, K>(arr1: T[], arr2: K[]): (T | K)[] {
    if (arr1.length != arr2.length) {
        throw new Error("两个数组长度不等");
    }
    let result: (T | K)[] = [];
    for (let i = 0; i < arr1.length; i++) {
        result.push(arr1[i]);
        result.push(arr2[i]);
    }
    return result;
}

const result = mixinArray([1, 3, 4], ["a", "b", "c"]);

result.forEach(r => console.log(r));

// const o = {
//     name:"xiaohua",
//     age:22,
//     gender:"男"
// }

// const newO = nameToUpperCase(o);

// console.log(newO.name); // xiaohua