类型兼容与赋值
为什么要有类型兼容
因为实际工作中,往往无法做到类型一致

比如在上面的 JS 代码中,假设 runTask
函数的参数只接受具有 a
、b
、c
这 3 个 key
的对象,但在一般情况下,即使我们多传一个 d
,也不会报错
你有的,我都有,则我能代替你;
y 有的,x 都有,则 x 兼容 y
简单类型的兼容
类型小的兼容类型大的

注意:图中的大小圆应当是包含关系,即小圆应该在大圆内部,此处为了展示清晰将小圆挪到了外部,后面的图示亦如此
集合 hi
小于集合 A
,因此将 hi
赋值给 a
不报错
普通对象的兼容
属性多的兼容属性少的
对象属性越多,限制越多,表示的集合范围越小,所以其实还是类型小的兼容类型大的

注意:对象兼容的前提是必须得存在共同的属性,此处两个对象共同的属性是
name
和age
兼容的情况下,作为参数也不报错
1 | type Person = { name: string; age: number } |
接口的兼容
子接口兼容父接口

函数的兼容
函数的兼容比较复杂,需要考虑参数和返回值
参数个数不同
存在相同类型的参数的函数,参数少的兼容参数多的

如何理解上图中的兼容关系?(图中绿色箭头代表可以兼容,红色箭头表示不能兼容)
如何理解上图中的代码?(图中绿色箭头代表可以兼容,红色箭头表示不能兼容)
主要看划线的右边参数的部分:
- 从上往下看,箭头全绿(
a
和b
都是number
) - 从下往上看,存在红色的箭头(参数
s
没有可以兼容的参数)
因此 接受一个参数的函数
兼容 接受两个参数的函数
,反过来则不行
为什么容忍参数变少呢?从下例中可以窥探一二

参数类型不同
对参数要求少的兼容对参数要求多的

从前面的例子我们知道,MyMouseEvent
是兼容 MyEvent
的,这里函数的兼容关系就正好反过来了。
返回值不同
不考虑参数类型的情况下,函数的兼容关系和返回值的兼容关系保持一致

思考:如果函数的参数和返回值同时存在且兼容关系相反呢?
实际工作中的函数
1 | interface Event { |
在不关闭 TS 严格检查的情况下,可以通过设置 "strictFunctionTypes": false
来避免函数报错
1 | // tsconfig.json |
