亲爱的小伙伴们,今天我们来聊聊TypeScript中的泛型。如果你还不了解泛型,那你可能错过了TS中最强大的特性之一。不要担心,跟着我一起学,保证你学会之后会感叹:早知道泛型这么好用,我当初怎么没早点学呢!

什么是泛型?

泛型可以理解为"广泛的类型"。它允许我们在定义函数、接口或类的时候,不预先指定具体的类型,而在使用的时候再指定类型的一种特性。

听起来有点抽象?没关系,让我们看个例子:

function identity<T>(arg: T): T {
    return arg;
}

这个identity函数就是一个最简单的泛型函数。它可以接受任何类型的参数,并返回与参数相同类型的值。我们使用<T>来声明一个类型变量T,这个T可以捕获用户传入的类型。

为什么要用泛型?

你可能会问,为什么要用泛型呢?直接用any不行吗?

function identity(arg: any): any {
    return arg;
}

确实,用any也能达到类似的效果。但是,使用any会丢失一些信息:传入的类型与返回的类型应该是相同的。如果我们传入一个数字,我们希望返回的也应该是一个数字。

泛型给我们提供了一种方法来保留这些信息,同时也提供了类型检查的能力。

泛型函数

让我们来看一个更实际的例子:

function reverse<T>(array: T[]): T[] {
    return array.reverse();
}

const numbers = reverse([1, 2, 3, 4, 5]);  // 类型是 number[]
const strings = reverse(["a", "b", "c"]);  // 类型是 string[]

在这个例子中,我们定义了一个泛型函数reverse,它可以反转任何类型的数组。TypeScript会根据我们传入的参数自动推断出T的类型。

泛型接口

泛型不仅可以用于函数,还可以用于接口:

interface Box<T> {
    value: T;
}

let numberBox: Box<number> = { value: 10 };
let stringBox: Box<string> = { value: "Hello World" };

这里我们定义了一个泛型接口Box,它可以包含任何类型的值。

泛型类

类也可以使用泛型:

class Queue<T> {
    private data: T[] = [];
    
    push(item: T) {
        this.data.push(item);
    }
    
    pop(): T | undefined {
        return this.data.shift();
    }
}

const numberQueue = new Queue<number>();
numberQueue.push(10);
numberQueue.push(20);
console.log(numberQueue.pop());  // 输出 10

这个Queue类可以存储任何类型的数据。我们在创建实例的时候指定具体的类型。

泛型约束

有时候我们希望限制泛型可以代表的类型范围。这时候我们可以使用泛型约束:

interface Lengthwise {
    length: number;
}

function loggingIdentity<T extends Lengthwise>(arg: T): T {
    console.log(arg.length);  // 现在我们知道arg有length属性
    return arg;
}

在这个例子中,我们使用extends关键字来约束泛型T必须符合接口Lengthwise的形状,也就是说,它必须有一个length属性。

在泛型约束中使用类型参数

你甚至可以声明一个类型参数,这个类型参数被其他类型参数所约束:

function getProperty<T, K extends keyof T>(obj: T, key: K) {
    return obj[key];
}

let x = { a: 1, b: 2, c: 3, d: 4 };

getProperty(x, "a"); // 没问题
getProperty(x, "m"); // 错误:参数"m"不能赋给类型"a" | "b" | "c" | "d"

这个getProperty函数接受一个对象和一个属性名,并返回对应的属性值。通过使用泛型约束,我们可以确保我们不会意外地访问对象上不存在的属性。

结语

泛型是TypeScript中非常强大的特性,它让我们能够编写更加灵活、可重用的代码,同时还能保持类型安全。当然,学习泛型可能需要一些时间来理解和掌握,但是相信我,一旦你掌握了泛型,你会发现它在日常编程中的无数应用场景。

还在等什么?赶紧打开你的IDE,开始尝试使用泛型吧!相信我,你会爱上它的。如果你觉得这篇文章对你有帮助,别忘了点赞分享哦!下次我们再见!

海码面试 小程序

包含最新面试经验分享,面试真题解析,全栈2000+题目库,前后端面试技术手册详解;无论您是校招还是社招面试还是想提升编程能力,都能从容面对~


AI新物种
1 声望2 粉丝