第四节 类型系统进阶-泛型的核心作用与约束

发布于:2025-06-13 ⋅ 阅读:(19) ⋅ 点赞:(0)

一、泛型的核心作用

1. ​​类型参数化(核心本质)​

泛型通过类型变量(如 <T>)实现​​动态类型绑定​​,使组件(函数/类/接口)在定义时不固定类型,使用时再指定,避免重复代码。

function identity<T>(value: T): T { 
  return value; 
}
const num = identity<number>(10); // T → number
const str = identity<string>("TS"); // T → string
2. ​​类型安全 vs Any​
  • any​:完全绕过类型检查(危险)
  • ​泛型​​:保持输入输出类型关联(安全)
// 泛型保留类型关联
function push<T>(arr: T[], item: T): T[] { 
  return [...arr, item]; 
}
push([1, 2], "3"); // 错误:string 不能赋值给 number
3. ​​代码复用与抽象​

泛型允许编写​​通用逻辑​​,适应多种数据类型:

  • ​数据容器​​(如通用数组操作)
    class DataStorage<T> {
      private items: T[] = [];
      add(item: T) { this.items.push(item) }
    }
    const strStorage = new DataStorage<string>();
  • ​API响应结构​​(统一处理不同数据类型)
    interface ApiResponse<T> {
      status: string;
      data: T; // T 可适配 User/Product 等任意类型
    }

二、泛型约束的核心机制

1. ​​基础约束(extends)​

限制泛型必须满足特定结构,避免运行时错误:

interface HasLength { length: number; }

function logLength<T extends HasLength>(obj: T): void {
  console.log(obj.length); // 安全访问
}
logLength("hello"); // ✅ length=5
logLength(42); // ❌ 数字无 length 属性
2. ​keyof 约束(属性安全访问)​

确保操作的属性名属于对象:

function getProp<T, K extends keyof T>(obj: T, key: K): T[K] {
  return obj[key]; // 编译器验证 key 有效性
}
const user = { name: "Alice", age: 30 };
getProp(user, "name"); // ✅
getProp(user, "email"); // ❌ 属性不存在
3. ​​工厂模式约束(构造安全)​

强制类构造函数符合特定签名:

class Test { constructor(public x: number) {} }

function create<T>(ctor: new (x: number) => T, val: number): T {
  return new ctor(val); // 约束 ctor 必须有 number 参数
}
create(Test, 10); // ✅
create(String, "hi"); // ❌ String 构造函数不匹配

三、高级工程实践

1. ​​多重约束(& 交叉类型)​

要求泛型同时满足多个条件:

interface Named { name: string; }
interface Aged { age: number; }

function printInfo<T extends Named & Aged>(obj: T): void {
  console.log(`${obj.name}, ${obj.age}`);
}
printInfo({ name: "Bob", age: 25 }); // ✅
printInfo({ name: "Bob" }); // ❌ 缺少 age
2. ​​默认类型(简化调用)​

为泛型参数提供默认值,减少冗余类型标注:

function createArray<T = string>(len: number, val: T): T[] {
  return Array(len).fill(val);
}
const strArr = createArray(3, "x"); // T 默认为 string
const numArr = createArray<number>(3, 1); // 显式覆盖
3. ​​工具类型结合​

泛型与 Partial/Readonly 等工具类型协同:

type ReadonlyStorage<T> = Readonly<DataStorage<T>>;
const readOnlyNumStore: ReadonlyStorage<number> = ... // 禁止修改

四、典型应用场景总结

​场景​ ​泛型方案​ ​优势​
​数据容器​ class Stack<T> {...} 一套逻辑处理任意类型数据
​API 响应封装​ interface Response<T> 统一结构适配不同业务数据
​工具函数​ function merge<T>(arr1: T[], arr2: T[]) 避免重复实现相似逻辑
​高阶组件(React)​ const HOC = <P>(Comp: ComponentType<P>) Props 类型透传

💡 ​​核心价值总结​​:
泛型通过 ​​类型参数化 + 约束机制​​,在 ​​灵活性​​(支持多类型)与 ​​安全性​​(编译时类型检查)之间取得平衡,是构建大型 TS 工程的基石技术。