学习typescript--------进阶
类型别名
给类型起个新名字(常用于联合类型) type Name = string type NameResolver = () => string type NameOrResolver = Name | NameResolver function getName (n: NameOrResolver) :Name { if (typeof n === 'string') { return n } return n() }
字符串字面量类型
约束取值只能为几个中的一个
type EventNames = 'click' | 'scroll' | 'mouseover' function handleEvent (el: Element, event: EventNames) {} handleEvent(document.getElementById('abc'), 'click') // right handleEvent(document.getElementById('abc'), 'mouseenter') // error event不能为mouseenter
元祖
数组合并了相同类型的对象,元祖是用来合并不同类型的对象的 let tom: [string, number] = ['abc', 123] 当为元祖添加越界元素时,越界元素的类型为元祖中每个类型的联合类型 tom.push('444') // right tom.push(false) // wrong
枚举
枚举是对标准数据类型的补充,来表达一组有区别的常量 enum direction { top, bottom, left, right } 这个相当于手动赋值的 top = 0, 后面的会依次加1,而且还要避免重复赋值的情况
枚举项又分为常数项和计算所得项
类
类的概念:
- 类: 定义了一种事务的抽象,包含它的属性和方法
- 对象:类的实例,通过new生成
- 面向对象的三大特点:封装,继承和多态
- 封装:将数据的操作细节隐藏,只暴露对外的接口。调用方不需要知道内部细节,只需要通过提供的接口就能访问该对象。同时调用方也不能任意的更改内部的数据
- 继承:子类继承父类,子类除了拥有父类的所有特性,还有一些子类自己的特性
- 多态:有继承产生的相关的不同的类,对相同的属性和方法进行不同的实现。
- 存取器:用以改变属性的读取和赋值行为
- 修饰符:用于限定成员和类型的性质,比如public表示公有属性或方法
- 抽象类:抽象类是其他类继承的基类,抽象类不允许被实例化,抽象类中的抽象方法必须在子类中被实现
- 接口:不同类之间共有的属性或方法,可以抽象成一个接口。接口可以被类实现。
es6中的类的用法
属性和方法:使用class来定义类,使用constructor定义构造函数,通过new生成实例时会自动调用构造函数
类的继承:使用extends实现继承,子类中使用super来调用父类的构造函数和方法
存取器:使用getter和setter进行属性的改变和读取
静态方法:使用static的方法为静态方法,不需要实例化,直接通过类来调用
es7中类的用法
es6中实例的属性只能通过构造函数中this.xxx来定义,es7中可以在类中直接定义
class Person{ name = 'tom' constructor(){} } let p = new Person() p.name // tom
es7提案可以使用static来定义静态属性
typescript中类的用法:
1,修饰符 public(共有的) private(私有的,不能在类的外部访问)和protected(和private类似,区别是可以在子类中访问)
2,readonly:只读属性,只读属性必须在声明时或构造函数里被初始化
3,参数属性:直接在构造函数的参数里面定义并初始化类中的成员
4,存取器:使用getter和setter
5,静态属性:static关键字, 通过类来调用或取值
6,抽象类:作为基类来使用,使用abstract关键字来定义抽象类和在抽象类中的抽象方法。抽象类不能被实例化。不同于接口,抽象类可以包含成员的具体实现,
抽象类中的抽象方法不包含具体实现并必须在子类中实现。抽象方法的语法与接口方法相似。都是定义方法签名但不包含方法体。
7,把类当作接口使用: 类定义会创建两个东西:类的实例类型和一个构造函数。因为类可以创建出类型,所以可以在允许使用接口的地方使用类
类与接口
1,类实现接口
接口可以对类的一部分进行抽象。可以使用implements关键字来实现。 一个类可以实现多个接口
2,接口继承接口
3,接口继承类: 因为类在创建的时候,会创建当前类的类型。
泛型
泛型指在定义函数、接口或类的时候,不预先指定具体的类型,在使用的时候再指定类型的一种特性
function createArray<T>(n: number, value: T): Array<T> { let result = [] for (let i = 0; i < n; i++){ result.push(value) } return result } createArray(3, '123') createArray<number>(2, 111)
多个类型参数
function reverseArray<T, U>(arr: <U, T>): [U, T] { return [arr[1], arr[0]] }
泛型约束
interface LengthWise { length: number } function loggingIdentify <T extends LengthWise>(arg: T): T { console.log(arg.length) return arg }
泛型接口
interface CreateArrayFn<T>{ (length: number, value: T): Array<T> } let createArray: CreateArrayFn<any> createArray = function<T>(length: number, value: T): Array<T>{ let result:<T>[] = [] for (let i = 0; i < length; i++) { result.push(value) } return result }
泛型类
class Gnumber<T>{ zeroN: T add: (x:T, y:T) => T } let g = new Gnumber<string>() g.zeroN = 'abc'
声明合并
如果定义了两个相同名字的函数、接口或者类,它们会合并为一个类型
函数的合并: 函数重载
接口的合并:
interface A{ price: number }
interface A { weight: number }
等同于:
interface A {
price: number
weight: number
}
注意: 合并属性的类型必须是唯一, 接口中方法的合并和函数的合并一样。