interface

interface 是对象的模板

interface Person {
    firstName: string;
    lastLame: string;
    age: number;
}

在上面的示例中,定义了一个接口 Person,它指定一个对象模板,拥有三个属性,类型分别为 stringstring、和 number。任何实现这个接口的对象,都必须实现这三个属性,并且必须符合属性的类型。

const per: Person = {
    firstName: "Jogn",
    lastName: "Smith",
    age: 20,
};

方括号运算符可以取出 interface 中某个属性的类型。

type T = Person["age"]; // number

interface 可以表示对象的各种语法,它的成员有 5 种形式。

  • 对象属性

  • 对象的属性索引

  • 对象方法

  • 函数

  • 构造函数

对象属性

在上面示例中,x 和 y 都是对象的属性,分别使用冒号指定每个属性的类型。

如果属性是可选的,就在属性后面加上一个问号。

如果属性是只读的,需要加上 readonly 修饰符。

对象的属性索引

在上面示例中,[prop: string]就是属性的字符串索引,表示属性名只要是字符串,都符合类型要求。

属性索引有 stringnumbersymbol 三种类型。

一个接口中,最多只能定义一个字符串索引。字符串索引会约束该类型中所有名字为字符串的属性。

上面示例中,属性索引制定所有名称为字符串的属性,它们的值必须是数值。因此属性 a 的值为布尔值就报错了。

属性的数值索引,其实是制定数组的类型。

一个接口中最多只能定义一个数值索引,数值索引会约束所有名称为数值的属性。

如果一个接口中同时定义了字符串索引和数值索引,那么数值索引必须服从于字符串索引。因为在 JavaScript 中,数值属性名最终是自动转换成字符串属性名。

对象的方法

属性名可以采用表达式,所以下面的写法也是可以的。

类型方法重载。

interface 里面的方法重载,不需要给出具体实现,

函数

interface 也可用于声明独立的函数。

构造函数

interface 内部可以使用 new 关键字,表示构造函数。

继承

interface 可以通过继承其他类型,来扩展自身类型,主要有下面几种情况。

interface 继承 interface

interface 可以使用 extends 关键字,继承其他 interface

interface 允许多种继承。

circle-exclamation

多重继承时,如果多个父接口存在同名属性,那么这些同名属性不能有类型冲突,否则会报错。

interface 继承 type

circle-exclamation

interface 继承 class

interface 还可以继承 class,即继承该类的所有成员。

接口合并

多个同名接口会合并成一个接口。

上面示例中,两个 Box 接口会合并成一个接口,同时有 heightwidthlength 三个属性。

同名接口合并时,同一个属性如果有多个类型声明,彼此不能有类型冲突。

同名接口合并时,如果同名方法有不同的类型声明,那么会发生函数重载。而且,后面的定义比前面的定义具有更高的优先级。

interface 与 type 的异同

  • 相同点:interface命令与type命令作用类似,都可以表示对象类型。

  • 不同点

    • type 能够表示非对象类型,而 interface 只能表示对象类型(包括数组、函数等)。

    • interface 可以继承其他类型,type 不支持继承,只能通过 & 运算符实现属性扩展。

    • 同名 interface 会自动合并,同名 type 则会报错。

    • interface 不能包含属性映射(mapping),type 可以。

    • this 关键字只能用于 interface

    • type 可以扩展原始数据类型,interface 不行。