简介
interface 是对象的模板,可以看作是一种类型约定,中文译为“接口”。使用了某个模板的对象,就拥有了指定的类型结构
interface 可以表示对象的各种语法,它的成员有5种形式
interface 的继承
interface 可以继承其他类型,主要有下面几种情况
接口合并
举例来说,Web 网页开发经常会对 windows 对象和 document 对象添加自定义属性,但是 TypeScript 会报错,因为原始定义没有这些属性。解决方法就是把自定义属性写成 interface,合并进原始定义
同名接口合并时,如果同名方法有不同的类型声明,那么会发生函数重载。而且,后面的定义比前面的定义具有更高的优先级
上面示例中,clone()方法有不同的类型声明,会发生函数重载。这时,越靠后的定义,优先级越高,排在函数重载的越前面。比如, clone(animal: Animal) 是最先出现的类型声明,就排在函数重载的最后,属于 clone() 函数最后匹配的类型。这个规则有一个例外。同名方法之中,如果有一个参数是字面量类型,字面量类型有更高的优先级
一个实际的例子是 Document 对象的 createElement() 方法,它会根据参数的不同,而生成不同的 HTML 节点对象
上面示例中,createElement() 方法的函数重载,参数为字面量的类型声明会排到最前面,返回具体的 HTML 节点对象。类型越不具体的参数,排在越后面,返回通用的 HTML 节点对象。如果两个 interface 组成的联合类型存在同名属性,那么该属性的类型也是联合类型
上面示例中,接口 Circle 和 Rectangle 组成一个 **联合类型 Circle | Rectangle。因此,这个联合类型的同名属性 area,也是一个联合类型**。本例中的 declare 命令表示变量s的具体定义,由其他脚本文件给出
interface 与 type 的异同
它们的相似之处,首先表现在都能为对象类型起名。class 命令也有类似作用,通过定义一个类,同时定义一个对象类型。但是,它会创造一个值,编译后依然存在。如果只是单纯想要一个类型,应该使用 type 或 interface
区别有下面几点
- type能够表示非对象类型,而interface只能表示对象类型(包括数组、函数等)
- interface可以继承其他类型,type不支持继承
- 同名interface会自动合并,同名type则会报错
- interface不能包含属性映射(mapping),type可以
- this关键字只能用于interface
- type 可以扩展原始数据类型,interface 不行
- interface无法表达某些复杂类型(比如交叉类型和联合类型),但是type可以
综上所述:如果有复杂的类型运算,那么没有其他选择只能使用type;一般情况下,interface灵活性比较高,便于扩充类型或自动合并,建议优先使用