typescript是一种给javascript添加特性的语言扩展。
扩展功能包括:
- 类型批注和编译时类型检查
- 类型推断
- 类型擦除
- 接口
- 枚举
- Mixin
- 泛型编程
- 名字空间
- 元组
- Await
变量声明
let [变量名]: [数据类型] = 值
数据类型
- any 任意类型
声明为any的变量可以赋予任意类型的值
不明确变量类型时使用;
改写现有代码时,在编译时选择性的包含或者移除类型检查
定义存储各种类型数据的数组 let arr: any[] = [12, ‘s’, false, {a: 1}];
- number 数据类型
双精度64位浮点值,用来表示整数或者分数 - string 字符串
- boolean 布尔类型
- 数组类型
两种声明方式
let list: number[] = [1,2]
元素类型+[]let list: Array<number> = [1,2]
Array<数据类型>
- 元组类型
元组类型用来表示已知元素数量和类型的数组,对应位置的元素类型要与声明的位置相同
let x: [string, number];
x = ['string', 12] // correct
x = [12, 'str'] // incorrect
- 枚举类型
用于定义数值集合
enum Color {Red, Green, Blue}; // Red对应的值是0, 往后依次加一。相当于{Red: 0, Green: 1, Blue: 2}
let c: Color = Color.Red;
console.log(c) // 0
// 可以指定值
enum Color {Red = 2, Green, Blue}
// 如果某个属性值是计算出来的,那么它后面紧跟的属性必须初始化
const getValue() {return 0}
enum List {
A = getValue(),
B = 3,
C
}// B必须初始化,后面的值按照默认规则,依次加一, 所以C是4
- void
标识方法返回值的类型, 表示该方法没有返回值
如果给一个变量定义为void类型,这个值只能是undefined或者null
带参数的函数
function add(param1: string, params: number) {}
可选参数(可选参数只能出现在后面)
function add(param1: number, param2?: number) {}
默认值
function add (param1: number, param2: number = 3) {}
剩余参数(利用es6的展开运算符)
function add(param1: number, …param2: number[]) {}
function add(…param: number[]) {}
- null
- undefined
- never 从来不会出现的值
类型推断
如果没有给出类型,ts编译器会根据值的类型来推断;如果推断不出来就默认是any类型
let num = 'string' // 此时编译器推断出num是string类型
num = 12 // 此时再赋值, 因为值的类型不是string所以会报错
联合类型
let val: string | number = 12; // val 可以是字符串或者数字类型
// 联合类型数组
let arr:number[] | string[] = [1,2,4] // arr可以是字符串数组或者数字数组
枚举
- 枚举值和枚举名可以反向映射;
- 枚举名不能是数字,数字字符串也不行;
- 枚举值默认从0 开始依次加一;
- 枚举值可以手动指定,默认是只能指定常数表达式(数字,或一元, 二元运算都是常数表达式);
- 指定字符串时候可以使用类型断言来避免类型检测;
- 当枚举值是个计算值时,紧跟其后的枚举值必需指定默认值,不然ts无法计算;
enum fundTypeEnum {
'全部账户' = <any>'a',
'账期' = 1,
'虚拟账户' = 2,
'信用金' = 3,
'现金账户' = 4,
};
接口
接口是一系列抽象方法的声明,是一些方法特征的集合。
这些方法都应该是抽象的,需要具体的类实现,然后第三方就可以通过这组抽象方法调用,让具体的类执行具体的方法。
interface IPerson {
firstName: string,
lastName: string,
sayHi: () => string,
func?: () => void
}
接口继承可以用extends
类
类的相关概念
- 类: 定义了一件事物的抽象热点,包含它的属性和方法
- 对象: 类的实例, 通过new 生成
- 面向对象的三大特性: 封装, 继承, 多态
- 封装: 把对数据操作的细节隐藏起来,自暴露对外的接口,外界不需要知道具体实现细节,同时也保证了外界无法随意更改对象内部的数据
- 继承: 子类继承父类,之类除了拥有父类的所有特性外,还有一些更加具体的特性
- 多态: 继承产生的相关的不同类,对同一个方法有不同的响应,(对从父类继承来的方法有自己独特的实现定义)
- 存取器: 改变属性的读取和赋值行为(getter & setter)
- 修饰器: 修饰符是一些关键字,用于限定成员或类型的性质,比如public表示公有属性或方法;
- 抽象类: 抽象类是提供其他类继承的基类,抽象类不允许被实例化;抽象类中的抽象方法必需在子类中实现
- 接口: 不同类之间公有的属性或方法,可以抽象成一个接口,接口可是被类实现,一个类只能继承自另一个类,但是可以实现多个接口;
类包含三个部分: 字段, 构造函数, 方法
class Car {
// 字段
engine:string;
// 静态属性
static name: string;
public age: number; // 属性和方法是公有的,可以在任何地方被访问到。默认所有的属性和方法都是pubic
// 构造函数 , 通过new生成新实例时,会自动调用构造函数。
constructor(engine:string) {
this.engine = engine
}
// 私有方法,不能在声明它的类外部访问;不允许在子类中访问
private setAge(): number {};
// 受保护的,可以在子类中访问
protected func(): void {};
// 静态方法 , 不需要实例化,直接通过类来调用
static disp():void {
console.log("发动机为 : "+this.engine)
}
get engine () {}
set engine () {}
}
类实现接口可以用implements
类型断言
可以用来手动指定一个值的类型
类型断言只能避免编译阶段进行类型检测,无法避免运行时的错误
语法
- 值 as 类型
- <类型>值
在tsx中只能用第一个写法 “值 as 类型”
用途
- 将一个联合类型断言为其中一个类型。因为当不确定到底是哪个类型的时候,只能访问他们共有的属性和方法。
- 将一个父类断言为一个更加具体的子类
- 将任何一个类型断言为any
- 将any断言为任何一个具体的类型
限制
并不是任何一个类型都可以被断言为任何另一个类型
A兼容B, 那么A能够被断言为B, B也能被断言为A
interface Animal {
name: string;
}
// ts是结构类型系统,类型之间的对比只会比较他们最终的结构
// interface Cat extends Animal {
// run(): void;
// }
interface Cat {
name: string;
run(): void;
}
let tom: Cat = {
name: 'tom',
run: () => {}
}
// Animal 兼容 Cat, 他们之间可以相互断言
let animal: Animal = tom;