Typescript入门系列:

TypeScript入门—类型二三事(一)
TypeScript入门—类型二三事(二) TypeScript入门—高级类型 Typescript入门——接口与类

接口

object表示非原始类型,也就是除number,string,boolean,symbol,null或undefined之外的类型,我们一般使用接口来定义对象的类型.
typeScript 中的接口是一个非常灵活的概念,除了可用于对类的一部分进行抽象以外,也常用于对「对象的形状(Shape)」进行描述。

interface Car {
  speed: number;
  color?: string;  // 可选属性
  readonly price: number // 只读属性
  [propName: string]: any // 额外属性
}
let car1 : Car = {
  speed: 200,
  price: 300,
  color: 'blue', 
}
let car2 : Car = {
  speed: 100,
  price: 200,
  name: 'mycar'
}
car2.price = 400 // error
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

上面定一个了一个接口,赋值的时候,变量的形状必须和接口的形状保持一致。但是接口包含了,可选属性,只读属性,额外属性。这会允许变量会不一样。

  • 可选属性在属性后面添加一个?,表示变量中该属性可以不存在。
  • 只读属性在属性前面加上readonly即可,表示变量对对象赋值后不可变更(只读的约束存在于第一次给对象赋值的时候,而不是第一次给只读属性赋值的时候)
  • 额外属性通常以[propName: [string]]: any表示,表示对象允许有一个值任意属性

需要注意的是,一旦定义了任意属性的类型,那么确定属性和可选属性的类型都必须是它的类型的子集.
任意属性的值允许是string,但是可选属性speed的值却是 number,number 不是 string 的子属性,因此会报错。

interface Car {
  speed: number;
  color?: string;  
  [propName: string]: string 
}
let car2 : Car = { // error 
  speed: 100,
  color: 'blue',
  name: 'mycar'
}
1
2
3
4
5
6
7
8
9
10

接口同样可以应用于数组:NumberArray 表示: index 的类型是 number,值的类型也是 number

interface NumberArray {
    [index: number]: number;
}
let foo: NumberArray = [1, 2, 4, 3, 9];
interface StringArray {
    [index: number]: string;
}
let bar: StringArray = ['1', '2', '4', '3', '9'];
1
2
3
4
5
6
7
8

Typescript中类的写法如下:

class Animal {
    name: string;
    constructor(name: string) {
        this.name = name;
    }
    sayHi(): string {
      return `My name is ${this.name}`;
    }
}

let a: Animal = new Animal('Jack');
console.log(a.sayHi()); // My name is Jack
1
2
3
4
5
6
7
8
9
10
11
12

public private 和 protected

  • public 修饰的属性或方法是公有的,可以在任何地方被访问到,默认所有的属性和方法都是 public 的
  • private 修饰的属性或方法是私有的,不能在声明它的类的外部访问
  • protected 修饰的属性或方法是受保护的,它和 private 类似,区别是它在子类中也是允许被访问的

当成员被标记pubilc后,所有直接访问实例当属性都是允许的。

class Person {
    public name: string;
    public constructor(name: string) {
        this.name = name;
    }
}
let a = new Person('Jack');
console.log(a.name); // Jack
a.name = 'Tom';
console.log(a.name); // Tom
1
2
3
4
5
6
7
8
9
10

当成员被标记成 private时,它就不能在声明它的类的外部访问

class Animal {
    Person name: string;
    constructor(name: string) { this.name = name; }
}

let a = new Person('Jack');
console.log(a.name); // error
a.name = 'Tom';
console.log(a.name); // error
1
2
3
4
5
6
7
8
9

protected修饰符与 private修饰符的行为很相似,但有一点不同, protected成员在派生类中仍然可以访问。

class Person {
    protected name: string;
    public constructor(name: string) {
        this.name = name;
    }
}

class Sporter extends Person {
    constructor(name: string) {
        super(name);
        console.log(this.name);
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13

抽象类
抽象类做为其它派生类的基类使用。 它们一般不会直接被实例化, 不同于接口,抽象类可以包含成员的实现细节。abstract关键字是用于定义抽象类和在抽象类内部定义抽象方法.并且抽象类中的抽象方法必需被子类实现。

abstract class Animal {
    abstract makeSound(): void;
    move(): void {
        console.log('roaming the earch...');
    }
}
class Cat extends Animal {
    makeSound() {
        console.log('meao!meao!')
    }
}
1
2
3
4
5
6
7
8
9
10
11

类实现接口
实现(implements)是面向对象中的一个重要概念。一般来讲,一个类只能继承自另一个类,有时候不同类之间可以有一些共有的特性,这时候就可以把特性提取成接口(interfaces),用 implements 关键字来实现。这个特性大大提高了面向对象的灵活性

interface Alarm {
    alert();
}

class Door {
}

class SecurityDoor extends Door implements Alarm {
    alert() {
        console.log('SecurityDoor alert');
    }
}

class Car implements Alarm {
    alert() {
        console.log('Car alert');
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

一个类可以实现多个接口

interface Alarm {
    alert();
}

interface Light {
    lightOn();
    lightOff();
}

class Car implements Alarm, Light {
    alert() {
        console.log('Car alert');
    }
    lightOn() {
        console.log('Car light on');
    }
    lightOff() {
        console.log('Car light off');
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

接口继承接口
接口与接口之间可以是继承关系

interface Alarm {
    alert();
}

interface LightableAlarm extends Alarm {
    lightOn();
    lightOff();
}
1
2
3
4
5
6
7
8

接口继承类
接口也可以继承类

class Point {
    x: number;
    y: number;
}

interface Point3d extends Point {
    z: number;
}

let point3d: Point3d = {x: 1, y: 2, z: 3};
1
2
3
4
5
6
7
8
9
10
最后更新时间: 10/8/2019, 7:41:17 PM