当前位置: 首页 > news >正文

TypeScript 泛型详解及应用场景

泛型(Generics)是 TypeScript 的核心特性,它允许我们编写可复用、类型安全的代码,同时保持灵活性。以下是深度解析和实际应用指南:


一、泛型基础概念

本质:参数化类型,将类型作为变量传递,像函数参数一样动态指定。

想象普通函数的参数是 值的变量,而泛型的参数是 类型的变量

  • T 就是一个类型变量,调用时才确定具体类型

  • 就像函数运行时才接收具体值一样,泛型在调用时接收具体类型

// 定义泛型函数
function identity<T>(arg: T): T {
  return arg;
}

// 使用
const output1 = identity<string>("hello"); // 显式指定 T 为 string
const output2 = identity(42);              // 自动推断 T 为 number

二、泛型核心应用场景
1. 函数/方法泛型

典型场景:处理多种类型输入但逻辑相同的函数。

// 返回数组第一项
function firstElement<T>(arr: T[]): T | undefined {
  return arr[0];
}

const str = firstElement(["a", "b"]); // T 推断为 string
const num = firstElement([1, 2]);     // T 推断为 number
2. 接口/类型泛型

典型场景:定义可复用的数据结构模板。

interface ApiResponse<T> {
  code: number;
  data: T;
  message: string;
}

// 使用
type UserResponse = ApiResponse<{ name: string; age: number }>;
const res: UserResponse = {
  code: 200,
  data: { name: "Alice", age: 30 },
  message: "success"
};
3. 类泛型

典型场景:可定制化的类实现。

class Box<T> {
  private content: T;

  constructor(value: T) {
    this.content = value;
  }

  getValue(): T {
    return this.content;
  }
}

const stringBox = new Box("hello");
const numberBox = new Box(42);
4. 约束泛型(Constraints)

典型场景:限制泛型参数必须满足某些条件。

interface HasLength {
  length: number;
}

function logLength<T extends HasLength>(arg: T): void {
  console.log(arg.length);
}

logLength("hello"); // OK,string 有 length 属性
logLength([1, 2]);  // OK,数组有 length
logLength(42);      // Error: number 没有 length
5. 默认泛型参数

典型场景:提供类型默认值。


interface Pagination<T = string> {
  items: T[];
  page: number;
}

const p1: Pagination = { items: ["a", "b"], page: 1 }; // T 默认为 string
const p2: Pagination<number> = { items: [1, 2], page: 1 };

三、高级泛型技巧
1. 条件类型(Conditional Types)

典型场景:根据输入类型动态决定输出类型。


type IsString<T> = T extends string ? true : false;

type A = IsString<"hello">; // true
type B = IsString<number>;  // false

四、实战应用案例
1. API 响应标准化

interface ApiResponse<T = any> {
  success: boolean;
  data: T;
  error?: string;
}

async function fetchUser(): Promise<ApiResponse<{ id: number; name: string }>> {
  const res = await axios.get("/user");
  return res.data;
}
2

3. 工具类型实现
// 实现 Partial、Pick、Omit 等工具类型
type MyPartial<T> = { [P in keyof T]?: T[P] };
type MyPick<T, K extends keyof T> = { [P in K]: T[P] };
type MyOmit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>;

五、泛型最佳实践
  1. 避免过度泛型:只在真正需要灵活性的地方使用。

  2. 明确约束:用 extends 限制泛型范围,增强类型安全。

  3. 优先推断:尽量让 TypeScript 自动推断类型参数。

  4. 命名规范:泛型变量通常用 TUKV 等大写字母。


六、常见问题解答

Q1: 泛型会影响运行时性能吗?
A: 不会,泛型是编译期特性,会在编译后被擦除。

Q2: 泛型和 any 的区别?
A: 泛型保留类型信息,any 完全放弃类型检查。泛型是类型安全的。

Q3: 如何解决泛型推断失败?
A: 显式指定类型参数或调整函数签名。

相关文章:

  • uniapp加载json动画
  • SGLang实战问题全解析:从分布式部署到性能调优的深度指南
  • CentOS系统安装详细教程
  • Go语言sync.Mutex包源码解读
  • 老硬件也能运行的Win11 IoT LTSC (OEM)物联网版
  • 总结一下常见的EasyExcel面试题
  • Lua 中,`if-else` 的详细用法
  • CVA6:支持 Linux 的 RISC-V CPU CORE-V
  • Leetcode - 周赛443
  • C++中的 友元关系
  • Python 序列构成的数组(当列表不是首选时)
  • SearXNG
  • Docker面试全攻略(一):镜像打包、容器运行与高频问题解析
  • mybatis的第五天学习笔记
  • 多模态大模型重塑自动驾驶:技术融合与实践路径全解析
  • @linux系统SSL证书转换(Openssl转换PFX)
  • 前端网页开发学习(HTML+CSS+JS)有这一篇就够!
  • 3dmax中VRay的3d导出glb的模型是黑白的,没有带贴图
  • K8s 老鸟的配置管理避雷手册
  • Android Input——输入系统介绍(一)
  • 买的网站可做360广告联盟吗/青岛网站权重提升
  • 哈尔滨建站哪个好/seo关键词排名点击工具
  • 自建网站支付问题/苹果要做搜索引擎
  • 深圳在哪些网站上面做推广/太原seo优化公司
  • 在网站上做支付功能 需要什么/个人网站怎么建立
  • 网站名称设置/百度反馈中心