22 泛型的使用 🌐之如何定义泛型函数
在上一篇中,我们讨论了泛型的基本概念,了解了什么是泛型以及为什么需要泛型。在本章中,我们将深入探讨如何定义和使用泛型函数,使我们的代码更加灵活和可重用。
1. 什么是泛型函数
泛型函数是一种可以接收任意类型参数的函数。通过使用泛型,我们可以编写与特定类型无关的代码,这样我们的函数在处理不同数据类型时依然能够保持类型安全。
1.1 定义泛型函数
在 TypeScript 中,我们可以通过在函数名称后面添加类型参数列表来定义一个泛型函数。类型参数使用尖括号(<T>
)表示,T
是一个常用的占位符名称,代表任何类型。
以下是一个简单的泛型函数示例:
1 | function identity<T>(arg: T): T { |
在这个示例中,identity
函数接受一个参数 arg
,它的类型是泛型 T
,返回值的类型也为 T
。这样,调用这个函数时,可以传入任何类型的值。
1.2 调用泛型函数
调用泛型函数时,TypeScript 可以自动推断出类型,或者你也可以手动指定类型。来看下面的例子:
1 | let output1 = identity<string>("Hello World"); // 手动指定类型 |
在第一个调用中,我们显式地指定了类型为 string
,而在第二个调用中,TypeScript 自动推断 arg
的类型为 number
。
2. 使用泛型约束
在某些情况下,我们可能希望对泛型参数施加一定的约束,以确保类型 T
拥有某些特性或属性。我们可以通过extends
关键字来实现。
2.1 约束泛型
例如,假设我们需要一个函数来获取长度的信息,我们可以这样定义:
1 | function logLength<T extends { length: number }>(arg: T): number { |
这里,我们使用了 T extends { length: number }
来约束泛型 T
必须具有 length
属性。这样,我们可以确保只传入具有 length
属性的类型。
2.2 调用约束泛型的函数
来看一下如何调用这个函数:
1 | console.log(logLength("Hello")); // 输出: 5 |
如上所示,字符串和数组都可以用于 logLength
,而数值类型因为没有 length
属性而无法调用。
3. 泛型函数的使用场景
泛型函数非常适合那些需要处理多种数据类型的函数。例如,数组处理函数、数据转换函数、API 请求处理等场景。下面是一个用于合并两个数组的泛型函数示例:
1 | function mergeArrays<T>(arr1: T[], arr2: T[]): T[] { |
在这个例子中,mergeArrays
是一个泛型函数,它接受两个类型为 T
的数组,然后将它们合并成一个新的数组。我们可以为任何类型的数组调用这个函数,从而实现高度重用的功能。
4. 小结
在本节中,我们学习了如何定义和使用泛型函数。通过定义泛型函数,我们可以编写更通用、更安全的代码,减少代码重复,让我们的函数适用于更多类型的输入。我们还探讨了如何使用泛型约束,以确保泛型类型拥有特定的属性。
接下来,我们将讨论泛型与接口的结合,并探讨如何利用其强大的特性来实现更复杂的类型安全和功能增强。敬请期待!
22 泛型的使用 🌐之如何定义泛型函数