看这一章时,感觉ts官网文档很不好理解,而ts入门教程则更好理解一点

什么是接口

在面向对象(OO)语言中

在面向对象语言中,接口(Interfaces)是一个很重要的概念,它是对行为的抽象,而具体如何行动需要由类(classes)去实现(implement)。

在TypeScript中

TypeScript中,接口有两个用处:

  1. 使用接口(Interfaces)来定义对象的类型,即对对象的形状(Shape)进行描述
  2. 对类的一部分行为进行抽象

1.用接口定义对象类型

简单示例

下面的例子中,定义了一个接口 Person,接着定义了一个变量 tom,类型是Person,这样就约束了tom的形状(Shape)必须与接口Person一致

接口命名一般需要首字母大写 有的编程语言中会建议接口的名称加上 I 前缀: Interface Naming Guidelines?redirectedfrom=MSDN)

  1. interface Person {
  2. name: string; // 注意,这里是分号结尾
  3. age: number;
  4. }
  5. // 这里赋值的属性、多一个,少一个都是不允许的
  6. let tom: Person = {
  7. name: 'Tom',
  8. age: 25
  9. }

可选属性

有时我们希望不要完全匹配一个形状(Shape),那么可以用可选属性

  1. interface Person {
  2. name: string;
  3. age?: number;
  4. }
  5. let tom: Person = { // OK
  6. name: 'Tom'
  7. }
  8. let tom2: Person = { // OK
  9. name: 'Tom2',
  10. age: 23
  11. }

任意属性

如果我们希望一个接口允许有任意的属性,可以使用如下方式

  1. interface Person {
  2. name: string; // 必要属性
  3. age?: number; // 可选属性
  4. [propName: stirng]: any;
  5. // 注意 任意属性的类型,必须包含必要属性和可选属性的类型
  6. // 如果上面任意属性类型不是any,而是number或string会报错
  7. }
  8. let tom: Person = {
  9. name: 'Tom',
  10. gender: 'male'
  11. }

只读属性

只读的约束是第一次给对象赋值时,而不是第一次给只读属性赋值的时候

  1. interface Person {
  2. readonly id: number; // 只读属性
  3. name: string; // 必要属性
  4. age?: number; // 可选属性
  5. [propName: stirng]: any;
  6. // 注意 任意属性的类型,必须包含必要属性和可选属性的类型
  7. // 如果上面任意属性类型不是any,而是number或string会报错
  8. }
  9. let tom: Person = {
  10. id: 89757,
  11. name: 'Tom',
  12. gender: 'male'
  13. }
  14. tom.id = 9527 // Error

2.对类的一部分行为进行抽象

有时候不同类之间可以有一些共有的特性,这时候就可以把特性提取成接口(interfaces),用 implements 关键字来实现。这个特性大大提高了面向对象的灵活性。

类实现接口

  1. interface Alarm {
  2. alert();
  3. }
  4. class Door {
  5. }
  6. // SecurityDoor 类实现了 Alarm 接口
  7. class SecurityDoor extends Door implements Alarm {
  8. alert() {
  9. console.log('SecurityDoor alert');
  10. }
  11. }
  12. class Car implements Alarm {
  13. alert() {
  14. console.log('Car alert');
  15. }
  16. }

一个类可以实现多个接口

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

接口继承接口

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

接口继承类

  1. class Point {
  2. x: number;
  3. y: number;
  4. }
  5. interface Point3d extends Point {
  6. z: number;
  7. }
  8. let point3d: Point3d = {x: 1, y: 2, z: 3};

混合类型

之前使用过接口来定义一个函数需要符合的形状

  1. interface SearchFunc {
  2. // 使用接口定义一个函数需要符合的形状
  3. (source: string, subString: string): boolean;
  4. }
  5. let mySearch: SearchFunc;
  6. mySearch = function(source: string, subString: string) {
  7. return source.includes(subString)
  8. }

一个函数可以有自定的属性和方法

  1. interface Counter {
  2. (start: number): string;
  3. interval: number;
  4. reset(): void;
  5. }
  6. function getCounter(): Counter {
  7. let counter = <Counter>function (start: number) { };
  8. counter.interval = 123;
  9. counter.reset = function () { };
  10. return counter;
  11. }
  12. let c = getCounter();
  13. c(10);
  14. c.reset();
  15. c.interval = 5.0;