7.泛型

一.指定函数参数类型

  • 单个泛型
const getArray = <T>(times:number,val:T):T[]=>{
    let result:T[] = [];
    for(let i = 0; i<times;i++){
        result.push(val);
    }
    return result;
}
getArray(3,3); // 3 => T => number
1
2
3
4
5
6
7
8
  • 多个泛型
function swap<T, K>(tuple: [T, K]): [K, T] {
    return [tuple[1], tuple[0]]
}
console.log(swap(['a','b']))
1
2
3
4

二.函数标注的方式

  • 类型别名
type TArray = <T, K>(tuple: [T, K]) => [K, T];
const getArray:TArray = <T, K>(tuple: [T, K]): [K, T] => {
    return [tuple[1], tuple[0]]
}
1
2
3
4

可以使用类型别名,但是类型别名不能被继承和实现。一般联合类型可以使用类型别名来声明

  • 接口
interface IArray{
    <T,K>(typle:[T,K]):[K,T]
}
const getArray:IArray = <T, K>(tuple: [T, K]): [K, T] => {
    return [tuple[1], tuple[0]]
}
1
2
3
4
5
6

能使用interface尽量使用interface

三.泛型接口使用

interface ISum<T> { // 这里的T是使用接口的时候传入
    <U>(a: T, b: T): U // 这里的U是调用函数的时候传入
}
let sum: ISum<number> = (a:number, b:number) => {
    return 3 as any
}
1
2
3
4
5
6

四.默认泛型

interface T2<T=string>{
    name:T
}
type T22 = T2;
let name1:T22 = {name:'zf'}
1
2
3
4
5

可以指定泛型的默认类型,方便使用

五.类中的泛型

  • 创建实例时提供类型
class MyArray<T>{ // T => number
    arr: T[] = [];
    add(num: T) {
        this.arr.push(num);
    }
    getMaxNum(): T {
        let arr = this.arr
        let max = arr[0];
        for (let i = 1; i < arr.length; i++) {
            let current = arr[i];
            current > max ? max = current : null
        }
        return max;
    }
}
let myArr = new MyArray<number>();
myArr.add(3);
myArr.add(1);
myArr.add(2);
console.log(myArr.getMaxNum());
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
  • 校验构造函数类型
const createClass = <T>(clazz: new(name:string,age:number)=>T):T =>{
    return new clazz(name,age);
}
createClass<Person2>(Person2)
1
2
3
4

六.泛型约束

  • 泛型必须包含某些属性
interface IWithLength {
    length:number
}
function getLen<T extends IWithLength>(val:T){
    return val.length;
}
getLen('hello');
1
2
3
4
5
6
7
const sum = <T extends number>(a: T, b: T): T => {
    return (a + b) as T
}
let r = sum<number>(1, 2);
1
2
3
4
  • 返回泛型中指定属性
const getVal = <T,K extends keyof T>(obj:T,key:K) : T[K]=>{
    return obj[key];
}
1
2
3