TypeScript完全解读(26课时)_11.TypeScript完全解读-类型推论和兼容性
11.TypeScript完全解读-类型推论和兼容性
在一些时候省略指令,ts会帮我们推断出省略的类型的地方适合的类型,通过学习ts的类型推论了解ts的推论规则
类型兼容性就是为了适应js灵活的特点,从而在一些情况下只要兼容的类型即可通过检测
创建文件并在index.ts中引入
类型推论
这里定义的name没有给他制定是什么类型的值,赋值一个字符串,ts就会给我们推断出name可能是想要一个字符串的类型
当我们再给这个name赋值一个数值类型就会报错 了。
多类型联合
我们不制定类型,ts会自动推断为联合类型
也就是这样,指定的情况
赋值为带布尔值的就不行了
都是通过等号右边的值,推断出左边的变量是什么类型的
上下文类型
根据等号左边去推断右边
js中的一些方法或者对象在ts中找不到,说明需要引入一些库
这里引入dom的库
这里绑定一个鼠标的点击事件
通过点.就可以把能访问的属性和方法都列出来
例如这里我访问一个.a因为是没有a这个属性的 就会报错。这里是因为已经推断出mouseEvent这个参数的类型。这就是根据左边的windows.onmousedown推断出了参数为鼠标的事件对象。这句是上下文类型
类型兼容性
定义一个接口Info,然后定义一个变量,infos类型是接口Info
然后再定义三个对象。 info1给infos赋值没有报错,是因为这个对象完全符合接口的定义
info2赋值给infoInterface就报错了
info3赋值也没有报错,首先要求必须有name字段。info3是有的,但是info3多了一个age是没有问题的,必须要有name,多了无所谓
接口内再加一个info的属性是一个对象,里面包含age属性,这样下面的两个赋值都会报错了。
给info1加上info这个对象,但是是个空的对象,也是会报错。
这样加上再赋值就不会报错了,age的类型也必须是数字类型的
函数的兼容性
11分44秒
返回的都为10.x赋值给y是没问题的
y赋值给x就会报错
错误。类型参数个数的要求后面的函数的参数个数必须小于等于左边的函数的参数个数
遍历数组arrs,用foEach其实其他的两个参数是用不到的
不写后面两个参数的情况
forEach要求三个函数,但是实际上我们只用到了一个参数,我们我复制的函数的参数的个数 一定是小于被赋值的参数个数的
函数参数类型的要求
y赋值给x参数类型不同就会报错
可选参数和剩余参数
这里实际上是一个数组的求和的操作
打印出来求和的结果
不用可选参数,传入三个参数arg1、arg2、arg3三个参数,最终返回三个参数的和
函数参数双向协变
22分10秒
使用箭头函数,里面什么都不定义
funcB赋值给funcA是可以的
A赋值给B也是可以的,funcA的类型既可以是number也可以是stirng类型
返回值类型
定义返回值类型是string或者number联合类型
y赋值给x没有问题,y是stirng类型,x既可以是string类型,也可以是number类型
x赋值给y就会报错了
z赋值给y也是报错。因为他们的返回值类型是不兼容的
函数重载
一定要使用function关键字来定义
虽然我的函数体定义的是any类型,还是会实际的检测出函数体的类型
传入两个number类型的数值,返回的就是number类型的
因为返回的是数字类型的,所以是没有lenth属性的,所以这里就会报错
他的类型实际上个接口,里面有两个函数重载
如果我这个是哦户给func赋sum函数就会报错,因为它缺少一个函数重载的情况。merge赋值给func之后,通过类型推论就会推断出func有两个函数重载,要包括这两种情况
这里使用sum给func赋值的话,这个sum只包含一种函数重载,是缺少一种情况的,所以之类就会报错,他俩是不兼容的。这个就是函数的兼容性
枚举
数字枚举类型和数字是互相兼容的
定义枚举类型StatusInterface
s是枚举类型StatusInterFace.On的值。
那么我给s赋值为1是可以的
赋值为2也是可以的。因为它是数字类型的。它是和数值类型是兼容的,只要给它赋的值数值类型就可以
给s赋值为另外一个枚举的的值,虽然他们表示的都是0,但是这个地方是不兼容的。数字枚举类型只与数字类型兼容。在不同枚举值之间是不兼容的
类的兼容性
定义三个类
再定义三个变量制定类型分别是这三个类。people赋值给animal是没有问题的
animal的类和people的类都有静态属性和构造函数,并animal的age类型是number类型。people的的age是string类型的
但是他们并不去监测类的静态成员和构造函数,它只会去比较实例上的成员,animal和people的实例都通过public name给实例上添加了name属性,而且类型都是stirng ,所以这两个类,类型是兼容的,所以把people复制给animal是没有问题的
但是foodIsClass没有静态成员。,只有给实例上添加了一个name属性,但是它的name是number类型的,虽然也是name但是类型是不兼容的,所以food复制给animal就会失败。。这就是监测实例上的成员
private和protected
类的私有成员和受保护成员,这两个修饰符修饰的成员会对兼容性造成影响,当检查类的实例的兼容性时。 如果目标类型(要被赋值的那个值,就是创建这个实例的类的类。)如果这各类包含一个私有成员,那么原类型(用来赋值的值)必须包含来自同一个类的这个私有成员
ParentClass和OtherClass是一模一样的,除了类名不一样
子类是可以赋值给父类的类型的值的
指定类型是ParentClass,但是创建实例用的是OtherClass是不行的。
类型居右私有属性“”age“”的单独声明
都换成protected也是一样的道理
泛型的兼容性
泛型包含类型参数,可以是任意类型,使用时类型参数会被制定为一个特定的类型。而这个类型只影响使用类型参数的部分
data1里面只要用到类型的变量的地方都是number类型
data2里面只要用到类型变量的地方都是string类型
data2赋值给data1是可以的。明明传进去的类型不一样,为什么可以赋值呢?因为接口Data<T>{}括号内什么都没有。所以这里不管是传number还是stirng都是没有影响的
可以理解为他俩可以是一个空对象
如果在接口里面定义实际的东西,定义data指定它的类型是T类型。现在赋值就不可以了,
因为data1里面要求它有一个data属性,类型是number
data2里面要求是stirng类型的