TypeScript类型兼容性:为什么鸭子类型很重要
🧑🏫 作者:全栈老李
📅 更新时间:2025 年 5 月
🧑💻 适合人群:前端初学者、进阶开发者
🚀 版权:本文由全栈老李原创,转载请注明出处。
今天咱们聊聊TypeScript里一个特别有意思的概念——类型兼容性,尤其是那个著名的"鸭子类型"。作为全栈老李,我在实际项目中发现很多同学对这个概念理解不够深入,导致在复杂类型系统中经常踩坑。
什么是鸭子类型?
先讲个段子:如果你看到一只鸟走起来像鸭子、游泳像鸭子、叫声像鸭子,那么这只鸟就可以被称为鸭子。这就是著名的"鸭子类型"(Duck Typing)的由来。
在TypeScript中,鸭子类型体现为"结构类型系统"(Structural Typing)。与Java/C#等语言的"名义类型系统"(Nominal Typing)不同,TypeScript判断两个类型是否兼容,不是看它们的名字是否相同,而是看它们的结构是否匹配。
// 全栈老李示例:鸭子类型的基本演示
interface Duck {
walk: () => void;
swim: () => void;
quack: () => void;
}
class FakeDuck {
walk() { console.log("走路像鸭子") }
swim() { console.log("游泳像鸭子") }
quack() { console.log("叫声像鸭子") }
// 即使多了一个方法也不影响类型兼容
extraMethod() { console.log("但我其实是只假鸭子") }
}
function makeDuckWalk(duck: Duck) {
duck.walk();
}
// 这里传入FakeDuck实例完全没问题!
makeDuckWalk(new FakeDuck()); // 输出:"走路像鸭子"