🎯 学习目标

  • 理解泛型约束的概念和作用
  • 掌握 extends 约束语法
  • 学会使用 keyof 进行约束
  • 了解多重约束

📝 基本约束

// 约束 T 必须有某些属性 interface HasId { id: number; } function findById<T extends HasId>(items: T[], id: number): T | undefined { return items.find(item => item.id === id); } interface User extends HasId { name: string; } const users: User[] = [ { id: 1, name: 'Alice' }, { id: 2, name: 'Bob' } ]; const user = findById(users, 1); // { id: 1, name: 'Alice' } // 没有 id 的数组会报错 const numbers = [1, 2, 3]; // findById(numbers, 1); // Error: number 不满足 HasId

🔧 keyof 约束

// 获取对象属性值的函数 function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] { return obj[key]; } const person = { name: 'Alice', age: 30, city: 'Beijing' }; const name = getProperty(person, 'name'); // string const age = getProperty(person, 'age'); // number // getProperty(person, 'email'); // Error: 'email' 不是 person 的属性 // 设置对象属性值的函数 function setProperty<T, K extends keyof T>(obj: T, key: K, value: T[K]): void { obj[key] = value; } setProperty(person, 'name', 'Bob'); setProperty(person, 'age', 31);

🔀 多重约束

interface HasId { id: number; } interface HasName { name: string; } // 多重约束:T 必须同时满足两个接口 function printEntity<T extends HasId & HasName>(entity: T): void { console.log(`ID: ${entity.id}, Name: ${entity.name}`); } interface User extends HasId, HasName { email: string; } const user: User = { id: 1, name: 'Alice', email: 'alice@example.com' }; printEntity(user); // 使用类型参数约束另一个类型参数 function createObject<K extends string, V>(key: K, value: V): Record<K, V> { return { [key]: value } as Record<K, V>; } const obj = createObject('name', 'Alice'); // { name: string }

📝 本节小结

  • • extends 用于约束泛型类型
  • • keyof 获取类型的所有键
  • • & 实现多重约束
  • • 约束让泛型更安全、更具体