一 建立类型思维
1)编程语言中的四种类型
强类型:不允许改变变量的数据类型,除非进行强制类型转换
弱类型:变量可以被赋值给不同的类型
静态类型:在编译阶段确定所有变量的类型
动态类型:在执行阶段确定所有变量的类型
2)JS语言类型:js是一门动态弱类型语言
动态类型缺点:如果是一个对象,动态类型会声明并存储属性名,运行时通过属性名访问,静态类型通过属性的偏移量访问,不用给属性名分配内存
弱类型缺点: 弱类型可能出现在声明和运行时,变量值不一致的现象
TS是拥有类型检查的JS的超集,可以编译成纯JS,也扩展了JS语言,TS在编译代码时,会进行严格的类型检查
二 TS类型及使用
-
TS都有哪些类型:JS的基本类型/any/never/void/元组/枚举/高级类型
-
TS常用类型说明 枚举:一组有名字的常量集合
1)编译之后是对象,枚举成员的名称和值都可以作为key和value2)枚举成员的值是只读类型,不能修改
3)枚举成员的类型分为两类,一类是const number,一类是computed number。const number会在编译时计算出结果,运行时会使用结果。computed number在运行时才会计算出结果
4)常量枚举,使用const声明的枚举称为常量枚举,常量枚举在编译阶段会被移除。会减少编译阶段的代码,当只需要一个对象的值的时候,可以用常量枚举
const enum a { b,c }
-
接口:可以用来约束对象、函数、类、混合类型
1)对象:可以固定对象的key,也可以使用可索引类型的接口,可索引类型既可以用数字索引,也可以用字符串索引
interface aa { [key: number]: string } 相当于定义了字符串类型的数组 let a1: aa = ['1', '2'];- 函数
interface b { (x: number,y: number): number }3)混合类型:一个对象可以作为函数使用,也可作为对象使用
-
函数类型
-
定义函数类型的四种方式
使用变量定义 let f1: (x: number, y: number) => number; // 会被编译成var f1; f1 = (a, b) => a + b;使用接口定义 interface b { (x: number,y: number): number } let f1: b = (a, b) => a + b;使用类型别名定义(type) type f1 = (x: number, y: number) => number;使用function形式定义,返回值可以通过类型推断使用 function f1(x: number, y: number) { return x + y } -
函数重载:不必为相同功能的函数定义不同的变量名
方法:需要使用函数声明先定义名称相同的重载列表,之后在最宽泛的函数声明中实现该函数 function add(x: number,y:number): number; function add(x: string, y: string): string; function add(x: any,y: any):any { if(typeof x == 'number') { return 1; } else if(typeof x == 'string') { return '1'; } }
-
类
1)抽象类:只能被继承,不能被实例化2)多态:在子类上针对相同的方法名有不同的实现
-
泛型:不预先规定类型,具体的类型要在使用时确定
1)某种程度上是函数重载和联合声明的优化
2)泛型用于泛型函数和泛型接口
-
高级类型
- 交叉类型和联合类型 交叉类型:将多个类型合并成一个类型
联合类型:声明的类型不确定,可以为多个类型中的一个,如果联合类型中有相同的属性,可以根据这个属性建立类型保护区块
interface aa { kind: 'aa', eat(): void; } interface bb { kind: 'bb', run(): void; } function cc(x: aa | bb) { switch (x.kind) { case 'aa': console.log(x.eat()); break; case 'bb': console.log(x.run()); } }
-
索引类型:keyof关键字可以声明一个对象的联合类型
-
映射类型:ts内置关键字,比如Record/Pick等
-
条件类型
三 声明文件及命名空间
三种类库声明文件的写法
1)全局库 在同级目录下添加.d.ts,用declare和namespace声明
2)模块类库 和全局类库声明差不多,但是要export
3)umd类库