Catalog
  1. 1. 接口是什么
  2. 2. 接口中可以定义什么样的内容
    1. 2.1. 带有属性的普通对象
    2. 2.2. 函数类型
    3. 2.3. 可索引的类型
  3. 3. 如何使用接口
    1. 3.1. 在函数形参中对入参的内容进行检查
    2. 3.2. 使用类去实现接口
      1. 3.2.1. 检查类的公共部分
      2. 3.2.2. 如何检查类的静态部分
    3. 3.3. 接口之间的继承
    4. 3.4. 用接口去继承类
  4. 4. 一个有意思的现象
Typescript 接口学习

接口是什么

  • 接口是为类型命名及你的代码,或第三方代码定义契约的,也就是所谓的 类型检查器

接口中可以定义什么样的内容

带有属性的普通对象

1
2
3
4
interface SquareConfig {
color?: string;
width?: number;
}

函数类型

参数名不需要于接口中定义的名字匹配

1
2
3
4
5
6
7
8
9
10
interface SearchFunc {
// 参数:返回值
(source: string, subString: string): boolean;
}

let mySearch: SearchFunc;
mySearch = function(src: string, sub: string): boolean {
let result = src.search(sub);
return result > -1;
}

可索引的类型

1
2
3
interface StringArray {
[index: number]: string;
}
  • typescript支持两种索引签名
    1. 字符串
    2. 数字
  • 需要注意的是:
    两种类型的索引签名同时使用时,数字类型的索引返回值必须是字符串索引返回值的子类型
    • 造成上述情况的原因是使用 number 来索引时,JavaScript会将它转换成string然后再去索引对象。 也就是说用 100(一个number)去索引等同于使用”100”(一个string)去索引,因此两者需要保持一致。

如何使用接口

在函数形参中对入参的内容进行检查

函数名(形参:接口名)

1
2
3
4
5
6
7
8
9
10
interface LabelledValue {
label: string;
}

function printLabel(labelledObj: LabelledValue) {
console.log(labelledObj.label);
}

let myObj = {size: 10, label: "Size 10 Object"};
printLabel(myObj);

使用类去实现接口

检查类的公共部分

class 类名 implements 接口名

1
2
3
4
5
6
7
8
interface ClockInterface {
currentTime: Date;
}

class Clock implements ClockInterface {
currentTime: Date;
constructor(h: number, m: number) { }
}
  • 当类实现接口时,只会检查类内的公共部分,但并不会检查静态部分(constructor

如何检查类的静态部分

  • 在之前对公共部分做的检查上追加内容

  • 理解官网上的举例

    1. 使用函数来接收类名及向构造函数中传递的参数

    2. 在函数的形参中对类进行检查

      • 检查的接口为

        1
        2
        3
        4
        5
        6
        interface ClockConstructor {
        new (hour: number, minute: number): ClockInterface;
        }
        interface ClockInterface {
        tick();
        }
        • 这里 ClockConstructor 接口应该为对类进行校验的模式
          • new 关键字做标识用来区别类和函数
          • (hour: number, minute: number) 用来检查构造函数
          • : ClockInterface 用来校验公共方法
    3. 在函数中返回类的实例

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      interface ClockConstructor {
      new (hour: number, minute: number): ClockInterface;
      }
      interface ClockInterface {
      tick();
      }

      function createClock(ctor: ClockConstructor, hour: number, minute: number): ClockInterface {
      return new ctor(hour, minute);
      }

      class AnalogClock implements ClockInterface {
      constructor(h: number, m: number) { }
      tick() {
      console.log("tick tock");
      }
      }

      let analog = createClock(AnalogClock, 7, 32);

接口之间的继承

interface 接口 extends 接口1,接口2
一个接口也可以继承多个接口,用,进行分割,增加重用性

1
2
3
4
5
6
7
8
9
10
11
interface Shape {
color: string;
}

interface PenStroke {
penWidth: number;
}

interface Square extends Shape, PenStroke {
sideLength: number;
}

用接口去继承类

1
2
3
4
5
6
7
8
9
10
11
class Control {
private state: any;
}

interface SelectableControl extends Control {
select(): void;
}

class Button extends Control implements SelectableControl {
select() { }
}
  • 接口会继承类的成员(不包括private和proptected),但不包括实现
  • 该接口类型只能被这个类或其子类所实现

一个有意思的现象

1
2
3
4
5
6
7
8
interface SquareConfig {
color?: string;
width?: number;
}

function createSquare(config: SquareConfig): { color: string; area: number } {
// ...
}
  • 如果向函数中直接传入对象字面量,则必须于类型完全匹配

    1
    2
    // height不在SquareConfig中声名,所以这里会报错
    let mySquare = createSquare({ height: 100, width: 100 });
  • 如果将这个对象赋值给一个另一个变量,便会绕过检查,不会报错了!

    1
    2
    3
    let squareOptions = { height: 100, width: 100 };
    // correct!!! 666666666666666666666666
    let mySquare = createSquare(squareOptions);
  • 当然,如果除了接口定义的属性外,还有其他不确定也不知道名字的属性…最佳的方式是添加一个字符串索引

    1
    2
    3
    4
    5
    interface SquareConfig {
    color?: string;
    width?: number;
    [propName: string]: any;
    }
Author: Helen
Link: http://be-awake.github.io/2019/10/14/typescript/typescript-interface/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.

Comment