TypeScript全解:类型兼容
为什么要兼容?
因为实际工作中,往往无法类型一致
假设我们现在需要设计一个接受参数为 一个对象包涵3个属性 的函数,但实际数据缺拥有更多属性,我们很容易写出以下代码:
1 | const data = { |
但是实际上我们并不会这么写,对于 JS程序员来说为什么要这么麻烦呢,虽然你只需要三个属性,我多传你几个,你不用不就好了,所以一般我们都会着那么写:
1 | const data = { |
所以 TS 需要适应这种习惯,他不能去纠正别人,如果故意把别人的习惯打破,那就很难去做推广
什么是类型兼容?
简单来说就是你就有的,我都有,则我们代替你,即:
y 有的,x都有,则 x 兼容 y
基本类型的兼容
1 | type A = string | number |
此时,字符串 ‘hi’范围更小缺兼容了范围更大的,,似乎有点违背上面的理论,此时我们用集合的方式来理解会更好
结论:子集当然可以赋值给父集
普通对象的兼容
1 | type Person = { |
如果用上面的结论,子集 => 父集
,那么对于对象来说, Person 和 user 那个范围更小呢?
其实通过逻辑推断来说,user 是更小的,因为属性多就是限制条件多,满足条件的就少,其实还是满足上述结论的,
但是为了方便记忆,我们可以得出对象的结论:属性多的可以赋值给属性少的
函数的兼容
相比下来函数会更复杂一点,函数不仅有属性,还包括参数和返回值
参数个数
直接上代码测试:
1 | const 接受一个参数的函数 = (n :number) => { |
很容易得出结论:参数少的兼容参数多的
如果还没理解的话,可以结合实际来看,我们经常在函数传参的时候,只会少写参数个数,比如在 axios 的调用、事件的绑定等等
1 | const button = document.getElementById('submit') |
在 JS 眼中,参数少传,问题不大,所以少写参数是很常见的
当然也许有杠精会说,我多传参数也问题不大啊。那么再想想看,实际你会去多传参数么?!基本不会吧~
参数类型
直接上代码测试:
1 | interface MyEvent { |
很容易得出结论:对参数要求少的兼容对参数要求多的,与普通对象的兼容相反
因为相比普通对象来说,函数的参数是要求别人的,所以和普通对象相反也能理解
我们再来看一个实际的栗子:
1 | interface Event { |
但是可以通过 TS 的配置让上面的代码正常运行
1 | // tsconfig.json |
特殊类型
直接上文档
加餐
顶类型和底类型
这两个概念不是 TS 的内容,但却是类型系统的知识
先上理论:底部类型可以赋值给顶部类型,用一张图来表示:
写在最后
虽然推论了这么多,但是你其实都不用记忆,什么小的兼容大的,少的兼容多的…
因为实际一使用,TS 就会你报错提示你