TypeScript 泛型入门到精通:TypeScript-New-Handbook 函数进阶实战教程

TypeScript 泛型入门到精通:TypeScript-New-Handbook 函数进阶实战教程 TypeScript 泛型入门到精通TypeScript-New-Handbook 函数进阶实战教程【免费下载链接】TypeScript-New-HandbookIncubation repository for the new TypeScript handbook 项目地址: https://gitcode.com/gh_mirrors/ty/TypeScript-New-HandbookTypeScript 泛型是类型系统的灵魂也是从新手走向进阶的必经之路。本文基于微软新手册项目TypeScript-New-Handbook的官方章节用最通俗的方式带你完成 TypeScript 泛型入门到精通的全过程从零开始理解泛型函数、类型推断、约束条件再到编写高质量泛型代码的实战技巧。无论你是刚接触 TypeScript 的新手还是想系统补全泛型知识的开发者这份 TypeScript 泛型教程都能帮你建立完整、正确的知识框架。什么是 TypeScript 泛型为什么你需要它泛型Generics的作用是描述两个值之间的类型对应关系。想象一个场景你写了一个函数想返回数组的第一个元素。不用泛型时返回值只能是any类型信息全部丢失function firstElement(arr: any[]) { return arr[0]; }而使用泛型后函数像搭桥一样把输入和输出的类型关联起来function firstElementT(arr: T[]): T { return arr[0]; } const s firstElement([a, b, c]); // s 的类型是 string const n firstElement([1, 2, 3]); // n 的类型是 number这就是 TypeScript 泛型最核心的价值一次编写处处保留类型安全。这部分内容源自官方手册的 More on Functions.md 章节是 TypeScript 泛型函数教学的标准起点。TypeScript 泛型函数类型推断机制详解很多初学者担心写泛型要手动声明一大堆类型参数其实完全不用。TypeScript 会根据你传入的参数**自动推断Inference**泛型类型。比如实现一个自己的map函数两个类型参数E和O都可以被自动推导出来function mapE, O(arr: E[], func: (arg: E) O): O[] { return arr.map(func); } const parsed map([1, 2, 3], n parseInt(n)); // number[]这里E从字符串数组推断为stringO从回调返回值推断为number。理解TypeScript 泛型类型推断是入门的关键一步多写几次这样的函数你就能自然掌握它。泛型约束 extends 用法限制类型的正确姿势有时我们不能让泛型接受任意类型而需要限定它必须拥有某些能力。这时用extends关键字添加约束Constraints。下面的函数要返回两个值中较长的一个因此要求传入的值必须有length属性function longestT extends { length: number }(a: T, b: T) { if (a.length b.length) { return a; } return b; } const longerArray longest([1, 2], [1, 2, 3]); // number[] const longerString longest(alice, bob); // string const notOK longest(10, 100); // ❌ 数字没有 length 属性泛型约束 extends 用法的核心要点约束让泛型只对特定类型子集开放同时让类型检查在编译期就拦住错误调用。约束值的常见陷阱注意约束只保证类型兼容不保证是同一个对象。下面的代码能通过编译但运行时会出问题function minimumLengthT extends { length: number }(obj: T, minimum: number): T { if (obj.length minimum) { return obj; } else { return { length: minimum }; // ❌ 返回了普通对象丢失了 T 的其它方法 } }函数承诺返回与传入相同的类型T实际却可能返回一个只有length的普通对象调用方调用slice等方法时就会崩溃。这是使用泛型约束时最经典的坑官方在 More on Functions.md 中有专门讲解。编写高质量 TypeScript 泛型函数的三大黄金法则写泛型容易上瘾一不小心就堆出过度设计的代码。官方手册总结了三条实用规则照着做就能写出高质量的泛型函数尽可能用类型参数本身而不是约束它两个看似相同的函数类型推断结果天差地别function firstElement1T(arr: T[]) { return arr[0]; } // 返回 T ✅ function firstElement2T extends any[](arr: T) { return arr[0]; } // 返回 any ❌尽量少用类型参数如果一个类型参数没有关联两个值它就是多余的。F在这里毫无意义只会让调用者困惑// ❌ F 没有关联任何值 function filter2T, F extends (arg: T) boolean(arr: T[], func: F): T[]; // ✅ 直接内联即可 function filter1T(arr: T[], func: (arg: T) boolean): T[];类型参数至少出现两次如果某个类型参数在函数签名里只出现一次说明它没在关联任何东西通常可以删掉// ❌ S 只出现一次 function greetS extends string(s: S) { console.log(Hello, s); } // ✅ 直接用 string function greet(s: string) { console.log(Hello, s); }记住泛型的本质是关联多个值的类型。这条法则贯穿 TypeScript 泛型入门到精通的始终。泛型对象类型与泛型类从 Box 到 Array泛型不止用于函数。接口、类型别名和类都可以是泛型的最常见的例子就是ArrayT、MapK, V、SetT和PromiseT。以经典的Box容器为例泛型让它一劳永逸interface BoxT { contents: T; } let box: Boxstring; // 等价于 { contents: string } type AppleBox BoxApple;泛型类也是一样实例化时类型参数自动推断class BoxT { contents: T; constructor(value: T) { this.contents value; } } const b new Box(hello!); // Boxstring⚠️ 注意泛型类的静态成员不能引用类自身的类型参数。因为类型在运行时会被完全擦除内存里只有一个Box.defaultValue如果允许Boxstring.defaultValue和Boxnumber.defaultValue各设各的就会互相覆盖。详细内容见 Object Types.md 和 Classes.md。进阶实战条件类型与 infer 推导当泛型遇到条件类型Conditional Types类型系统开始展现真正的威力。借助infer关键字你可以在条件分支中提取出类型type GetReturnTypeT T extends (...args: never[]) infer U ? U : never; type Foo GetReturnType() number; // number type Bar GetReturnType(x: string) string; // string再看一个自动剥开数组类型的例子type FlattenT T extends any[] ? T[number] : T; type Str Flattenstring[]; // string type Num Flattennumber; // number条件类型还能替代繁琐的函数重载。比如根据入参类型返回不同对象一个泛型函数即可搞定type NameOrIdT extends number | string T extends number ? IdLabel : NameLabel; function createLabelT extends number | string(idOrName: T): NameOrIdT { throw unimplemented; }这部分是 Types from Transformation.md 的核心内容属于泛型的进阶高阶用法建议在掌握基础后再深入。泛型函数重载与可选参数实战提醒学习函数进阶时还有两个和泛型同样重要的知识点需要留意可选参数标记为?的参数实际类型是number | undefined。给回调函数写可选参数时要格外小心——它表示回调可能只带一个参数被调用而不是你可以传两个参数。函数重载重载签名之外实现签名对外部不可见。能用联合类型参数如string | any[]时优先用联合类型而非重载代码更简单、调用更灵活。这两个主题与泛型函数一起构成了 TypeScript 函数类型体系的完整拼图全部收录在 More on Functions.md 中。总结TypeScript 泛型学习路径TypeScript 泛型入门到精通并不神秘按这条路径学习最有效率掌握泛型函数类型参数T、自动推断More on Functions.md学会泛型约束extends理解约束与同一对象的区别遵守三条黄金法则写出高质量泛型代码熟悉泛型对象类型与泛型类Object Types.md、Classes.md挑战条件类型与 infer解锁类型编程的高级玩法Types from Transformation.md如果你想完整阅读这份官方手册的全部章节可以直接查看项目源码所有章节都是清晰的 Markdown 文件非常适合自学和查阅。希望这篇 TypeScript 泛型实战教程能帮你扫清进阶路上的障碍写出更健壮、更优雅的类型安全代码【免费下载链接】TypeScript-New-HandbookIncubation repository for the new TypeScript handbook 项目地址: https://gitcode.com/gh_mirrors/ty/TypeScript-New-Handbook创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考