我正在参加「掘金·启航计划」
泛型
泛型是可以在保证类型安全前提下,让函数等与多种类型一起工作,从而实现复用,常用于:函数、接口、class 中。
例如,创建一个 id 函数,传入什么数据就返回该数据本身(也就是说,参数和返回值类型相同)。
function id(value: number): number { return value }
id(10) 调用以上函数就会直接返回 10 本身。但是,该函数只接收数值类型,无法用于其他类型。
为了能让函数能够接受任意类型,可以将参数类型修改为 any。但是,这样就失去了 TS 的类型保护,类型不安全。
function id(value: any): any { return value }
泛型在保证类型安全(不丢失类型信息)的同时,可以让函数等与多种不同的类型一起工作,灵活可复用。实际上,在 C# 和 Java 等编程语言中,泛型都是用来实现可复用组件功能的主要工具之一。
泛型函数
泛型函数是这样定义的。在函数名称的后面添加 <>(尖括号),尖括号中添加类型变量,比如此处的 Type。类型变量 Type,是一种特殊类型的变量,它处理类型而不是值。该类型变量相当于一个类型容器,能够捕获用户提供的类型(具体是什么类型由用户调用该函数时指定)。因为 Type 是类型,因此可以将其作为函数参数和返回值的类型,表示参数和返回值具有相同的类型。类型变量 Type,可以是任意合法的变量名称。
function id<Type>(value: Type): Type { return value }
function id<T>(value: T): T { return value }
调用泛型函数时在函数名称的后面添加 <>(尖括号),尖括号中指定具体的类型,比如,此处的 number。当传入类型 number 后,这个类型就会被函数声明时指定的类型变量 Type 捕获到。此时,Type 的类型就是 number,所以,函数 id 参数和返回值的类型也都是 number。同样,如果传入类型 string,函数 id 参数和返回值的类型就都是 string。这样,通过泛型就做到了让 id 函数与多种不同的类型一起工作,实现了复用的同时保证了类型安全。
const num = id<number>(10)
const str = id<string>('a')
简化泛型函数调用
在调用泛型函数时,可以省略 <类型> 来简化泛型函数的调用。此时,TS 内部会采用一种叫做类型参数推断的机制,来根据传入的实参自动推断出类型变量 Type 的类型。需要注意的是,当编译器无法推断类型或者推断的类型不准确时,就需要显式地传入类型参数。
// 省略 <number> 调用函数
let num = id(10)
let str = id('a')