前言
目标
…
1 class类
TS中的class,不仅提供了class语法,也作为一种类型存在
1.1 实例属性
给class添加实例成员
1.2 构造函数
构造函数语法规则:
成员初始化
(比如,age:number)后,才可以通过this.age来访问实例成员- 需要为构造函数
指定类型注解
,否则会被隐式推断为any; - 构造函数
不需要返回值
类型
1.3 实例方法
实例方法的类型注解(参数与返回值)与函数的相同
1.4 类的继承
类继承的两种方式: 1 extends 2 implements(实现接口)
1.4.1 extends
类Dog继承类Animal之后,实例化类Dog就可以调用类Animal中的方法或属性
1.4.2 implements
implements实现继承
- 通过
implements
关键字让class 实现接口 Person 类实现接口Singable - Person 类实现接口Singable意味着,Person类中必须提供Singable 接口中指定的
所有方法和属性
1.5 可见性修饰符
类成员可见性: 可以使用TS 来控制 class 的方法或属性对于 class 外的代码是否可见
可见性修饰符包括:
- public (公有的) —— 默认
- protected (受保护的)
- private (私有的)。
1.5.1 public可见的
在类属性或方法前面添加 public关键字,来修饰该属性或方法
是共有的
因为 public 是默认可见性,所以,可以直接省略
1.5.2 protected受保护的
protected: 表示受保护的
,仅对其声明所在类和子类中
(非实例对象)可见
1.5.3 private私有的
private: 表示私有的
,只在当前类中可见
,对实例对象以及子类也是不可见的。
1.6 readonly只读修饰符
readonly: 只能修饰属性,不能修饰方法
- 在class类中使用,表示只读,用来防止在
构造函数之外
对属性
进行赋值 - 在接口或{}对象中,表示属性只读
对象或接口只读属性,不可修改
2 类型兼容性
两种类型系统: 1StructuralType System (结构化类型系统) 2 NominalType System (标明类型系统)
TS
采用的是结构化类型系统
,也叫做 ducktyping(鸭子类型),类型检查关注的是值所具有的形状。
也就是说,在结构类型系统中,如果两个对象具有相同的形状
,则认为它们属于同一类型
。
‘’
Point与Ponint2D是两个不同名称的类,但是内部结构一样
变量p的类型被显示标注为Point类型,但是,它的值却是Point2D 的实例,并且没有类型错误。
因为TS是结构化类型系统
,只检查Point和 Point2D 的结构是否相同
(相同,都具有X和两个属性,属性类型也相同)
2.1 对象兼容性
成员多的可以赋值给成员少的
2.2 接口兼容性
接口之间的兼容性类似于class,且,class与interface接口之间也可以兼容
1 相同位置的参数类型要相同或者兼容
2 成员多的可以赋值给成员少的
2.3 函数兼容性
函数兼容性要考虑以下三个方面: 1 参数个数 2参数类型 3返回值类型
1 参数个数
参数少的可以赋值给参数多的
参数少的f1可以赋值给参数多的f2
2 参数类型
相同位置的参数类型要相同或者兼容
将定义的参数类型拆开
,参数少的可以赋值给参数多的
3 返回值类型
我们只需要关注返回值本身即可
若返回值是原始类型
,此时返回值类型相同
即可,例如F1和F2
若返回值是对象类型
,此时成员多的可以赋值给成员少
的,例如F3和F4
3 交叉类型
交叉类型(&)
:功能类似接口继承(extends),用于组合多个类型为一个类型
(常用于对象类型)
A与B交叉之后形成的C,有A与B中的属性
交叉类型与接口继承的区别
相同点:都可实现对象类型组合
不同点:对同名属性,处理冲突的方式不同
1 接口继承 - 同名属性
同名属性类型不同,使用接口继承会报错
2 交叉类型 - 同名属性
使用交叉类型,函数中参数冲突,会取两个类型
对象中的同名属性类型不同,会导致交叉报错
4 泛型和keyof
4.1 泛型的创建与使用
泛型
是可以在保证类型安全
前提下,让函数等与多种类型一起工作
,从而实现复用
,常用于: 函数
、接口
、class
中
创建一个泛型
类型变量Type
- 任意合法的变量名称,是一种特殊类型的变量
,它处理类型
而不是值。相当于一个类型容器,能够捕获用户提供的类型(具体类型由用户调用时指定)
使用泛型函数
推荐使用简化方式调用泛型函数
当编译器无法推断类型
或者推断的类型不准确
时,就需要显式地传入类型参数。
4.2 泛型的约束
泛型约束:默认情况下,泛型函数的类型变量Type可以代表多个类型,这导致无法访问任何属性。
例如:想获取参数长度,无法保证所有的Type类型都有length,number类型无length长度
1 指定更加具体的类型
指定取值和返回值类型为数组类型
2 添加约束
创建描述约束的接口ILength,该接口要求提供length属性
extends为该泛型添加约束
Type extends ILength
传入的Type类型要有length属性,即数组、字符串等
4.3 多个泛型变量
泛型的类型变量可以有多个,并且类型变量之间还可以约束。
创建一个函数,获取对象中属性的值
key
只能是Type所有键中的任何一个
传入的是对象,key可以是对象的属性
传入的是数组,key可以是数组的下标或者数组相关的方法等属性
4.4 泛型接口
泛型接口: 接口也可以配合泛型来使用,以增加其灵活性,增强其复用性
8创建泛型接口*
接口的类型变量Type
,接口中的所有成员都可以使用
使用泛型接口
需要显示
的指定具体的类型
,idFun< number >
扩展: 在TS中数组其实是一个泛型接口
定于一个数组,查看一下数组的提示Array< number > 类似于接口名<类型变量>
根据提示看一下Array数组的源码
在TS的找到了Array的接口源码,< T > 等同于< Type >,forEach在Array接口中的一个属性
4.5 泛型类
创建泛型类
使用泛型类
4.6 泛型工具类型
泛型工具类型: TS内置了一些常用的工具类型,来简化TS 中的一些常见操作。
说明:它们都是基于泛型实现
的(泛型适用于多种类型,更加通用),并且是内置的,可以直接在代码中使用这些工具类型有很多,常用的有以下四个
- Partial< Type>
- Readonly< Type>
- Pick<Type,keys>
- Record<Keys,Type>
4.6.1 Partial< Type >
Partial< Type > 用来构造(创建)一个类型,将Type的所有属性设为可选
4.6.2 Readonly< Type >
Readonly< Type > 用来构造一个类型,将Type 的所有属性都设置为 readonly
(只读)
4.6.3 Pick<Type,keys>
Pick<Type,Keys> 从 Type 中选择一组属性来构造新类型
Type 要选择谁的属性,Keys选择那几个属性(只能是Type属性中存在的属性
)
4.6.4 Record<Type,keys>
Record<Keys,Type> 构造一个对象类型
,属性键为Keys,属性类型为Type
keys作为属性名,Type作为属性类型,构造一个对象类型
5 索引签名类型和索引查询类型
索引类型签名:当无法确定对象中有哪些属性
(或者说对象中可以出现任意多个属性),此时,就用到索引签名类型了。
5.1 对象索引签名类型
创建一个索引对象类型
使用
可以根据需要向obj1中添加多个属性,变量属性必传
5.2 数组索引签名类型
数组类型
使用
5.3 索引查询
基本查询
查询方式类似于JS中的对象查询:obj[key]
多个查询
查询多个
proKeys[‘a’|‘b’]
查询所有
proKeys[keyof proKeys]
6 映射类型
映射类型: 基于旧类型创建新类型(对象类型),减少重复、提升开发效率,基于签名索引类型
6.1 映射类型使用
1 in 创建
根据以上代码 用映射类型简化ob的定义,obj1 与ob结构完全相同
映射类型是能在类型别名type中使用,不能在接口中使用
2 keyof 根据对象类型创建
6.2 基于映射类型实现的泛型工具Partial< Type>
先来看一下 Partial< Type >的作用: 用来构造(创建)一个类型,将Type的所有属性设为可选
ts源码中有关Partial的定义,[P in keyof T]
使用的是映射类型
T - 对象
P - 键名
T[P] - 键名对应的类型
根据Partial源码成创建一个Partial1实现 Partial一样的效果,可以看到使用之后可以实现一样的可选效果