TypScript的泛型

218 阅读1分钟
不预先定义好具体的类型,而在使用的时候在指定类型的一种特性

假设我们用一个函数,它可接受一个 number 参数并返回一个number 参数,如下写法:

function returnItem (para: number): number {
    return para
}

如果我们打算接受一个 string 类型,然后再返回 string类型,则如下写法:

function returnItem (para: string): string {
    return para
}

上述两种编写方式,存在一个最明显的问题在于,代码重复度比较高

虽然可以使用 any类型去替代,但这也并不是很好的方案,因为我们的目的是接收什么类型的参数返回什么类型的参数,即在运行时传入参数我们才能确定类型

这种情况就可以使用泛型,如下所示

function returnItem<T>(para: T): T {
    return para
}

可以看到,泛型给予开发者创造灵活、可重用代码的能力

函数声明
function returnItem<T>(para: T): T {
    return para
}
function swap<T, U>(tuple: [T, U]): [U, T] {
    return [tuple[1], tuple[0]];
}

swap([7, 'seven']); // ['seven', 7]
class Stack<T> {
    private arr: T[] = []

    public push(item: T) {
        this.arr.push(item)
    }

    public pop() {
        this.arr.pop()
    }
}

使用方式

const stack = new Stacn<number>()

如查只能传递 string 和 number 类型,这时就可以使用 <T extends xxx>实现约束泛型

type Parms = string | number
class Stack<T extends Parms>{
    private arr: T[] = []
    
    public push(item: T) {
        this.arr.push(item)
    }

    public pop() {
        this.arr.pop()
    }
}

索引

索引类型 keyof T 把传入的对象的属性类型取出生成一个联合类型,这里的泛型 U 被约束在这个联合类型中,如下所示:

function getValue<T extends object, U extends keyof T>(obj: T, key: U) {
  return obj[key] // ok
}