ts 泛型

什么是泛型?

型(Generics)允许定义 可复用、可适应不同类型 的代码,而不需要在编写时就确定具体的类型。

基础语法

1️⃣ 定义泛型函数

复制代码
function identity<T>(value: T): T {
  return value;
}

identity<number>(123);    // 指定 T 为 number
identity<string>("hello"); // 指定 T 为 string

```
*  T是一个 类型变量,表示函数可以接收任何类型。
* identity<number>(123) 表示把 T 指定为 number。
* 如果不指定,TS 会自动 类型推断:
```
identity(true); // T 被推断为 boolean

```

### 2️⃣ 泛型接口
```
interface ApiResponse<T> {
  code: number;
  message: string;
  data: T;
}

const res1: ApiResponse<string> = {
  code: 200,
  message: 'success',
  data: 'Hello World'
};

const res2: ApiResponse<number[]> = {
  code: 200,
  message: 'success',
  data: [1, 2, 3]
};

```
* ApiResponse<T> 表示 data 的类型是 泛型,可以是任何类型

### 3️⃣ 泛型类

```
class Box<T> {
  content: T;
  constructor(value: T) {
    this.content = value;
  }
}

const stringBox = new Box<string>('Hello');
const numberBox = new Box<number>(123);

```
> Box<T> 可以装任何类型的值,通过 new Box<string> 或 new Box<number> 来指定。

### 4️⃣ 泛型约束(extends)
有时候你希望泛型 必须满足某些条件,这时可以加 约束。
```
interface HasLength {
  length: number;
}

function getLength<T extends HasLength>(value: T): number {
  return value.length;
}

getLength('Hello'); // OK
getLength([1, 2, 3]); // OK
getLength(123); // ❌ Error: number 没有 length 属性

```
### 5️⃣ 泛型默认值
```
function getValue<T = string>(value: T): T {
  return value;
}

getValue('hello'); // 推断为 string
getValue(123);     // T 推断为 number

```
* 如果不传 T,默认是 string。

# 🚀 综合示例
```
type Field<T> = {
  label: string;
  value: T;
};

const nameField: Field<string> = { label: '姓名', value: '张三' };
const ageField: Field<number> = { label: '年龄', value: 18 };

```
## 🔥 泛型工具函数
```
function merge<T extends object, U extends object>(obj1: T, obj2: U): T & U {
  return { ...obj1, ...obj2 };
}

const combined = merge({ name: '张三' }, { age: 18 }); // { name: string, age: number }

```
## 🔥 泛型 in TSX 组件
```
// GenericList.tsx
type GenericListProps<T> = {
  items: T[];
  renderItem: (item: T) => JSX.Element;
};

function GenericList<T>({ items, renderItem }: GenericListProps<T>) {
  return <div>{items.map(renderItem)}</div>;
}

```
* 使用:
*
```
<GenericList
  items={[1, 2, 3]}
  renderItem={(item) => <p key={item}>{item}</p>}
/>

```
## 🧠 泛型和 React/TS 项目常见用法
| 场景       | 示例                    |
| -------- | --------------------- |
| API 响应类型 | `ApiResponse<T>`      |
| 通用工具函数   | `merge<T, U>()`       |
| 表单字段定义   | `Field<T>`            |
| 组件 props | `GenericComponent<T>` |
| 状态管理     | `useState<T>()`       |
| 事件处理     | `onChange<T>()`       |

##  总结一张图理解
```
function func<T>(param: T): T { ... }
          ↑
    类型占位符,等调用时再指定具体类型

```
* T 可以是任何名字(常用 T、U、K、V)
* T 的值可以通过 调用时指定 或 TS 自动推断
相关推荐
jin12332239 分钟前
基于React Native鸿蒙跨平台地址管理是许多电商、外卖、物流等应用的重要功能模块,实现了地址的添加、编辑、删除和设置默认等功能
javascript·react native·react.js·ecmascript·harmonyos
2501_920931701 小时前
React Native鸿蒙跨平台医疗健康类的血压记录,包括收缩压、舒张压、心率、日期、时间、备注和状态
javascript·react native·react.js·ecmascript·harmonyos
落霞的思绪1 小时前
配置React和React-dom为CDN引入
前端·react.js·前端框架
橙露2 小时前
React Hooks 深度解析:从基础使用到自定义 Hooks 的封装技巧
javascript·react.js·ecmascript
2501_920931702 小时前
React Native鸿蒙跨平台使用useState管理健康记录和过滤状态,支持多种健康数据类型(血压、体重等)并实现按类型过滤功能
javascript·react native·react.js·ecmascript·harmonyos
打小就很皮...2 小时前
dnd-kit 实现表格拖拽排序
前端·react.js·表格拖拽·dnd-kit
Ulyanov2 小时前
从静态到沉浸:打造惊艳的Web技术发展历程3D时间轴
前端·javascript·html5·gui开发
打小就很皮...2 小时前
React 19 + Vite 6 + SWC 构建优化实践
前端·react.js·vite·swc
Highcharts.js2 小时前
使用Highcharts与React集成 官网文档使用说明
前端·react.js·前端框架·react·highcharts·官方文档
VT.馒头3 小时前
【力扣】2625. 扁平化嵌套数组
前端·javascript·算法·leetcode·职场和发展·typescript