TypeScript类型兼容

先看个最简单的例子:接口赋值。TypeScript检查类型兼容性根本不关心具体类型名,只看结构是否匹配。比如你定义了一个Person接口,要求有name和age字段,这时候哪怕你拿一个Dog类型的对象过来,只要它恰好也有同名字段且类型匹配,TypeScript就会放行。这就是著名的"鸭子类型"------走起来像鸭子,叫起来像鸭子,那就是鸭子。

但这里有个细节要注意,源类型必须包含目标类型的所有必需属性。反过来就不行了:

函数兼容性就更有意思了。函数参数检查遵循"逆变"原则------听起来很玄乎,其实很简单:参数类型可以比定义的更宽泛,但不能更严格。比如下面这个例子:

为什么func2赋值给func1不行?因为func2定义时承诺能处理string和number,但func1只能处理number,如果把func2交给func1,碰到string参数就崩了。

返回值则相反,遵循"协变"------返回值类型必须更具体或完全相同:

数组和元组的兼容规则经常让人栽跟头。普通数组看类型参数是否兼容:

但元组就严格多了,必须长度和每个位置的类型都匹配:

枚举类型比较特殊,数字枚举和number互相兼容,但字符串枚举谁也不认:

类的兼容性规则有点反直觉。只比较实例成员,静态成员和构造函数不参与比较。而且private和protected成员会影响兼容性:

泛型兼容性最容易让人困惑。泛型本身不参与兼容性判断,最终看的是具体类型:

any类型在兼容性检查中是万能牌,但也很危险。unknown只能赋值给any和unknown自身,而never可以赋值给任何类型。

实际开发中,掌握这些规则能帮你避免很多奇怪的错误。特别是在使用第三方库时,经常需要自定义类型声明,理解兼容性规则就能写出更健壮的类型定义。记住TypeScript的类型系统是结构化的,这点和很多传统静态语言完全不同。

最后给个实用建议:当遇到复杂的类型兼容问题时,可以先把鼠标悬停在变量上查看推断出的类型,然后用类型断言临时绕过检查。但长期来说,还是应该理顺类型关系,毕竟类型安全的本质是为了减少运行时错误,而不是和编译器斗智斗勇。

相关推荐
低保和光头哪个先来4 分钟前
CSS+JS实现单例老虎机切换图片动画
前端·javascript·css
坐公交也用券7 分钟前
适用于vue3+pnpm项目自动化类型检查及构建的Python脚本
开发语言·javascript·python·typescript·自动化
IT_陈寒11 分钟前
Vue3性能优化实战:这5个技巧让我的应用加载速度提升了40%
前端·人工智能·后端
小小鸟00819 分钟前
Vue响应式原理
前端·javascript·vue.js
lee57621 分钟前
鄙人的 Vue 3.0 商业级开源甘特图已经发布到 npm
前端·vue.js·npm·开源·甘特图
前端老曹24 分钟前
vue3 三级路由无法缓存的终终终终终终极解决方案
前端·javascript·vue.js
零Suger24 分钟前
React Router v7数据模式使用指南
javascript·笔记·react.js
1024小神24 分钟前
uniapp + vue3 + scss 定义全局样式变量,并使用
前端·uni-app·scss
顾安r26 分钟前
12.17 脚本网页 创意导航
java·linux·前端·游戏·html
Q_Q51100828528 分钟前
小程序基于Java Web的健身房管理系统设计和开发
java·前端·小程序