Tailwind CSSTailwind CSS
Home
  • Tailwind CSS 书籍目录
  • Vue 3 开发实战指南
  • React 和 Next.js 学习
  • TypeScript
  • React开发框架书籍大纲
  • Shadcn学习大纲
  • Swift 编程语言:从入门到进阶
  • SwiftUI 学习指南
  • 函数式编程大纲
  • Swift 异步编程语言
  • Swift 协议化编程
  • SwiftUI MVVM 开发模式
  • SwiftUI 图表开发书籍
  • SwiftData
  • ArkTS编程语言:从入门到精通
  • 仓颉编程语言:从入门到精通
  • 鸿蒙手机客户端开发实战
  • WPF书籍
  • C#开发书籍
learn
  • Java编程语言
  • Kotlin 编程入门与实战
  • /python/outline.html
  • AI Agent
  • MCP (Model Context Protocol) 应用指南
  • 深度学习
  • 深度学习
  • 强化学习: 理论与实践
  • 扩散模型书籍
  • Agentic AI for Everyone
langchain
Home
  • Tailwind CSS 书籍目录
  • Vue 3 开发实战指南
  • React 和 Next.js 学习
  • TypeScript
  • React开发框架书籍大纲
  • Shadcn学习大纲
  • Swift 编程语言:从入门到进阶
  • SwiftUI 学习指南
  • 函数式编程大纲
  • Swift 异步编程语言
  • Swift 协议化编程
  • SwiftUI MVVM 开发模式
  • SwiftUI 图表开发书籍
  • SwiftData
  • ArkTS编程语言:从入门到精通
  • 仓颉编程语言:从入门到精通
  • 鸿蒙手机客户端开发实战
  • WPF书籍
  • C#开发书籍
learn
  • Java编程语言
  • Kotlin 编程入门与实战
  • /python/outline.html
  • AI Agent
  • MCP (Model Context Protocol) 应用指南
  • 深度学习
  • 深度学习
  • 强化学习: 理论与实践
  • 扩散模型书籍
  • Agentic AI for Everyone
langchain
  • 第6章:泛型

第6章:泛型

泛型约束

什么是泛型约束?

泛型约束(Generic Constraints)允许我们限制泛型类型参数的范围,确保它们满足特定条件。通过使用 extends 关键字,我们可以要求泛型类型必须符合某种结构或继承自某个基类。

基本语法

function example<T extends ConstraintType>(arg: T): T {
  // 函数体
}

其中:

  • T 是泛型类型参数。
  • ConstraintType 是约束条件,可以是接口、类或字面量类型。

典型应用场景

1. 确保属性存在

interface HasLength {
  length: number;
}

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

logLength("hello"); // 5
logLength([1, 2, 3]); // 3
logLength(42); // 错误:number 没有 length 属性

2. 结合 keyof 约束对象键

function getProperty<T, K extends keyof T>(obj: T, key: K) {
  return obj[key];
}

const person = { name: "Alice", age: 30 };
getProperty(person, "name"); // "Alice"
getProperty(person, "gender"); // 错误:gender 不是 person 的键

多重约束

TypeScript 支持通过交叉类型实现多重约束:

interface Printable {
  print(): void;
}

interface Loggable {
  log(): void;
}

function process<T extends Printable & Loggable>(item: T) {
  item.print();
  item.log();
}

常见问题与解决方案

问题1:过度约束

过度使用约束可能导致代码灵活性降低。建议:

  • 优先使用最小约束原则
  • 考虑使用类型守卫替代约束

问题2:循环约束

避免自引用的约束定义:

// 错误示例
interface Invalid<T extends Invalid<T>> {}

最佳实践

  1. 明确约束意图:约束应该清晰表达业务需求
  2. 文档化复杂约束:使用 JSDoc 说明约束条件
  3. 优先选择接口约束:比类约束更灵活
  4. 测试边界情况:验证约束在极端情况下的行为

示例:电商系统中的应用

interface Product {
  id: string;
  price: number;
}

class Cart<T extends Product> {
  private items: T[] = [];

  addItem(item: T) {
    this.items.push(item);
  }

  getTotal(): number {
    return this.items.reduce((sum, item) => sum + item.price, 0);
  }
}

思考题:如何设计一个泛型函数,要求参数必须是包含 id: string 的数组,且返回按 id 排序后的数组?

通过泛型约束,我们可以在保持类型安全的同时,实现高度可复用的代码逻辑。

Last Updated:: 3/27/25, 10:50 AM