引言
- 各种的类型的兼容方式不一样,是否兼容就看我们的类型赋予的时候是否安全
我们先来看一个例子
问题:base2能不能赋予给base1这个类型?
答案是不能的,因为多一个boolean是不安全的,base2有可能是boolean
在基本类型中范围大的不能赋予给范围小的,上面例子反过来就是可以的
接口的兼容性
- 对象的赋值,要看赋值的类型是否满足被赋值类型的所有特性,如果满足则可以赋值
- 但是这样赋值之后,frult只能点出来color,不能点出来taster,所以这样是安全的
- 但是反过来,frult赋值给veg,veg有可能使用taste属性,而这个frult里没有taste属性,所以这样是不安全的
函数的兼容性
- 参数的兼容性和返回值的兼容性
问题:f2可以赋值给f1么?
答案是不行的,因为当我们把f2赋值给f1后,f1本身是只能传两个参,但是f2要求必须传第三个参,所以这样做是不安全的,反过来就是可以的,因为定义了f2是可以接收三个参数,而使用时f1只需传两个参数就可以满足,是安全的
对于函数的参数而言,定义的参数个数需要大于等于使用的参数个数
函数返回值的兼容性
问题:这个例子,谁能赋值给谁呢?
答案f1可以赋值给f2,定义的时候返回值满足赋值的返回值类型
类的兼容性
- 鸭子类型检测 ,类型长的一样就可以赋值
多的可以赋值给少的,少的不能赋值给多的
- 类的兼容性,比较的是实例(对象)和接口就一致了,多的可以赋予给少的
- 如果一旦有了修饰符(除了public),那么就不能来回的兼容了
逆变
- 父亲能给儿子,就叫逆变
- 要从调用的角度来考虑,调的是fn2,fn2只能传parent,那么fn1可以处理
协变
- 返回值可以返回儿子,叫协变
ts配置文件有个开关,可以双向协变,就是你可以传父亲,也可以传儿子,返回值可以返回父亲,也可以返回儿子,相当于不校验了
- 参数就是双向协变了
总结:
- 传递可以是父亲,返回值可以是儿子
- 逆变和协变指的是个数,如果从一个值的类型个数来看,要从满足的角度来看,也就是要从安全性的角度来看
枚举的兼容性
- 枚举类型不存在兼容性
- 不能想换赋值
infer
- 推导类型
- 我们之前的文章里,内置类型都是通过extends+分发以及in、keyof关键字来实现的,我们可以基于infer来实现
- 只能配合extends用
ReturnType
- 取函数返回值类型
ReturnType实现
- infer R 你放在哪就会推断哪的值,上述例子中推断函数返回值的类型,赋值给R,外侧如果T满足是一个函数,返回刚才推断的这个函数的返回值类型
Parameters
- 拿到函数参数的类型
Parameters实现
- 推导的结果是个元祖
InstanceType
- 获取类的实例类型
ConstructorParameters
- 获取类的构造函数的参数类型
元组转联合类型
- 目标
- 实现