接口
| 12
 3
 4
 5
 6
 7
 8
 
 | interface labelValue {label : string
 }
 function printLabel2(obj: labelValue) {
 console.log(obj.label)
 }
 
 printLabel2(myObj)
 
 | 
duck-typing特性(鸭子类型)
- 检验两个比较的对象是否具有相同的属性及类型,b是否包含a
- 如person与Person的比较,虽然person的属性数量大于Person,但是person具有Person的所有属性且类型相同,所以,检验过程成功| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 
 | interface Person {name: string
 age: number
 sex: number
 }
 
 const person = {
 name: 'schnuffel',
 age: 18,
 sex: 1,
 msg: '1231312312'
 }
 
 const testFunc = (param: Person) => {
 return param
 }
 
 testFunc(person)
 
 |  
 
可选、只读属性:
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 
 | interface SquareConfig {color?: string
 readonly y: number
 }
 function createSquare(config: SquareConfig): { color: string; area: number } {
 
 let newSquare = {color: "white", area: 100}
 if (config.color) {
 newSquare.color = config.color
 }
 return newSquare
 }
 let mySquare = createSquare({color: "black"})
 let p1: SquareConfig = { y: 20 }
 
 | 
只读数组ReadonlyArray:创建后不能被修改
| 12
 3
 4
 
 | let a: number[] = [1, 2, 3, 4]let ro: ReadonlyArray<number> = a
 
 a = ro as number[]
 
 | 
额外的属性检查
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 
 | interface SquareConfig {color?: string
 width?: string
 }
 function createSquare(config:SquareConfig): {color: string; area: number}{}
 let mySquare = createSquare({ colour: "red", width: 100 })
 
 
 解决方法1:类型断言:
 let mySquare = createSquare({ width: 100, opacity: 0.5 } as SquareConfig)
 
 解决方法2:字符串索引签名(最佳):
 interface SquareConfig {
 color?: string;
 width?: number;
 [propName: string]: any;
 }
 
 解决方法3: 将这个对象赋值给另一个变量
 let squareOptions = { colour: "red", width: 100 }
 let mySquare = createSquare(squareOptions)
 
 | 
函数类型
| 12
 3
 4
 5
 6
 7
 8
 
 | interface SearchFunc {(source: string, subString: string): boolean
 }
 
 mySearch:SearchFunc = function(src: string, sub: string): boolean {
 let result = src.search(sub);
 return result > -1;
 }
 
 | 
可索引的类型
- ts支持两种索引签名:字符串和数字。可同时使用,但是数字索引的返回值必须是字符串索引返回值类型的子类型
- 可以设置为只读: readonly [index: number]: string| 12
 3
 
 | interface StringArray {[index: number]: string
 }
 
 |  
 
类类型
实现接口 implements
- 接口描述了类的公共部分。它不会帮你检查类是否具有某些私有成员。| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 
 | interface ClockInterface { currentTime: Date
 setTime(d: Date)
 }
 
 class Clock implements ClockInterface {
 currentTime: Date;
 setTime(d: Date) {
 this.currentTime = d
 }
 constructor(h: number, m: number) {}
 }
 
 |  
 
继承接口 extends
- 一个接口可以继承多个接口,继承多个接口的接口叫做合成接口| 12
 3
 4
 5
 
 | interface Square extends Shape, PenStroke { sideLength: number
 }
 
 let square = <Square>{}
 
 |  
 
混合接口:js使用第三方库时用
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 
 | interface Counter {(start: number): string;
 interval: number;
 reset(): void;
 }
 
 function getCounter(): Counter {
 let counter = <Counter>function (start: number) {}
 counter.interval = 123
 counter.reset = function () {}
 return counter
 }
 
 | 
接口继承类型
- 接口继承类,可继承类的私有属性和protected,但只能被这个类和它的子类实现| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 
 | class Control { private state: any
 }
 interface SelectableControl extends Control {
 select(): void
 }
 
 class Button extends Control implements SelectableControl {
 
 select() { }
 }
 
 class TextBox extends Control {
 
 select() { }
 }
 
 |  
 
类
通过extends的类叫做派生类或子类,而父类叫做基类或超类
修饰符
- public:默认,公共属性
- private:私有属性,不能在声明它的类的外部访问。
- private和protected在比较类型时,只有两个类型都有同样的修饰符,并且该修饰符来自同一基类时,才认为这两个类型是兼容的。| 12
 3
 4
 5
 6
 7
 8
 9
 10
 
 | class Animal {private name: string;
 constructor(theName: string) { this.name = theName }
 }
 
 class Rhino extends Animal {
 constructor() { super("Rhino") }
 }
 let animal = new Animal("Goat")
 let rhino = new Rhino()
 
 |  
 
 
- protected:保护属性
- 不能在声明它的类的外部访问,但派生类中仍然可以访问
- 构造函数也可以被标记成 protected。这意味着这个类不能在包含它的类外被实例化,但是能被继承
 
- readonly:只读修饰符,必须在声明时或构造函数里被初始化。
- static: 静态属性,只有当前类才有的属性
- abstract:抽象类
- 做为其它派生类的基类使用。 它们一般不会直接被实例化
- 定义的方法必须在派生类中实现,派生类的构造函数必须调用super()| 12
 3
 
 | let department: Department department = new 子类名()
 department.printName()
 
 |  
 
 
存取器:get和set成对出现
- get 变量名()
- set 变量名()| 12
 3
 4
 5
 6
 
 | getToken(): Itoken {return Initoken
 },
 setToken( tokenData: Itoken ): Itoken {
 return ( Initoken = { ...Initoken, ...tokenData } )
 }
 
 |  
 
构造函数
- 类定义会创建两个东西:类的实例类型和一个构造函数。| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 
 | class Greeter {static standardGreeting = "Hello,there"
 greeting: string
 constructor(message: string) {
 this.greeting = message
 },
 greet() {
 return "Hello, " + this.greeting
 }
 }
 
 let greeter: Greeter
 greeter = new Greeter("world")
 
 let greeterMaker: typeof Greeter = Greeter
 greeterMaker.standardGreeting = "Hey there!"
 
 |  
 
把类当做接口使用
- 类可以创建出类型,所以在允许使用接口的地方可以使用类| 12
 3
 4
 5
 6
 7
 8
 
 | class Point {x: number
 y: number
 }
 
 interface Point3d extends Point {
 z: number
 }
 
 |  
 
es5 vs es6 的类区别
- es6:class类必须new调用,不能直接执行
- 不存在变量提升
- 无法遍历它实例原型链上的属性和方法
 
- es5:类和普通函数无区别,可以执行