Skip to content
Go back

Typescript——泛型

Published:  at  07:00 AM

一、问题的引入

需求:创建一个函数,我想要传入啥参数,就返回啥,传入的参数和返回的值的类型相同,那么针对这个需求,我们应该如何去做,大家很快就会想到下面的这种办法。

function hhh(value: number): number { return value }

但是这样写只能接收数字们不能适合其他的类型,这样就不能实现需求,

那这样写呢?

function hhh(value: any): any { return value }

这样将参数的类型修改成any,这个能实现,但是意义在哪,这不就失去了TS最本身的对类型的保护了吗,这样写实在是不安全。

那么我们该如何写:

function hhh<Type>(value: Type): Type { return value }

function hhh<T>(value: T): T { return value }

二、什么是泛型?

泛型就是可以在保证类型安全的前提下,让函数等多种类型一起工作,从而去实现复用。

常见使用的地方:函数、接口、class中。

定义泛型函数:

function hhh<Type>(value: Type): Type { return value }

function hhh<T>(value: T): T { return value }

在函数名称的后面添加 <>(尖括号),尖括号中添加类型变量,比如此处的 Type ,是一种特殊类型的变量,它处理类型而不是值该类型变量相当于一个类型容器,能够捕获用户提供的类型,就是你写的是啥类型,就会可以给你捕获出来,可以实现任意合法变量传入和返回值需求的实现。

泛型函数的调用:

const num = hhh<number>(10)
const str = hhh<string>('a')

简化的写法:

// 省略 <number> 调用函数
let num = hhh(10)
let str = hhh('a')

三、泛型的约束

默认情况下,泛型函数的类型变量 Type 可以代表多个类型,这导致无法访问任何属性,比如length属性,这个时候就要为泛型添加约束来收缩类型。有两个方式:

直接指定添加的具体的类型

function id<Type>(value: Type[]): Type[] {
  console.log(value.length)
  return value
}

这个时候就能访问这个length属性了。

添加约束

  1. 创建描述约束的接口 ILength,该接口要求提供 length 属性

  2. 通过 extends关键字使用该接口,为泛型(类型变量)添加约束

  3. 该约束表示:传入的类型必须具有 length 属性

// 创建一个接口
interface ILength { length: number }
// Type extends ILength 添加泛型约束
function hhh<Type extends ILength>(value: Type): Type {
  console.log(value.length)
  return value
}

四、泛型可以有多个变量类型

泛型的类型变量可以有多个,并且类型变量之间还可以约束(比如,第二个类型变量受第一个类型变量约束) 比如,创建一个函数来获取对象中属性的值:

function hhh<Type, Key extends keyof Type>(obj: Type, key: Key) {
  return obj[key]
}
let person = { name: 'jack', age: 18 }
hhh(person, 'name')

五、泛型接口和泛型的配合

// 泛型接口作为函数返回值类型
interface Result<T> {
  success: boolean;
  data: T;
}

// 函数返回泛型接口,适配不同返回值类型
function getResult<T>(data: T): Result<T> {
  return { success: true, data };
}

// 使用:传入字符串,返回Result<string>
const res1 = getResult("Hello 泛型");
// 传入对象,返回Result<{name: string}>
const res2 = getResult({ name: "张三" });

六、总结

核心解决的问题

泛型弥补了 “单一类型函数复用性差” 和 “any 类型丢失类型保护” 的缺陷,既能实现函数 / 接口 / 类的通用化,又能严格约束输入输出的类型一致性。

核心语法与使用

关键扩展能力

核心优势

兼顾 “复用性” 与 “类型安全”,避免重复编写相似的类型定义,同时保留 TS 的类型校验能力,是实现通用化、可扩展 TS 代码的核心手段。


Suggest Changes
Share this post on:

Previous Post
分享会(Vue3父子间通信以及TS的实现方式)
Next Post
JS中的事件循环(Event Loop)