typescript里面 interface 和 type 的区别
标题的这个问题,最近面试遇到了四五次。
今天来解决一下
一、type和interface的定义
type关键字可以定义一个集合,可以包含各种类型的属性和值,以用来描述对象、函数、联合类型、交叉类型等。
type A = string; // 声明了一个类型别名A,同时它的类型等价于string类型
它的主要作用是对一组类型或一个特定类型结构进行封装,以便于在其它地方进行复用。
比如抽离一组联合类型
type StatusCode = 200 | 301 | 400 | 500 | 502; type PossibleDataTypes = string | number | (() => unknown); const status: StatusCode = 502;
声明一个对象类型
type Person = { name: string; age: number; sex: 0 | 1; };
interface: 它定义了一个对象的形状,描述了对象应该具有的属性及类型
interface Person{ name:string; age:number; sex:0 | 1; }
通过上面示例可以看出,它们两个描述对象结构时的语法略有不同。type使用等号来定义类型别名,而interface使用花括号直接定义接口的成员。
二 、type 和 interface 的可扩展性
interface: 可以通过声明合并来扩展。这意味着你可以多次声明同一个接口,并将它们合并为一个。接口支持扩展多个接口,提供了一种强大的方式来构建和契约。
interface Person{ name:string; } interface Person{ age:number } // 上面的两个等价于下面这个 interface Person{ name:string; age:number }
也可以使用extends 关键字进行继承
interface Fruit{ name:string } interface Apple extends Fruit{ kind:stirng }
type: 不能通过声明合并来扩展。 但是可以通过联合类型( | )和交叉类型(&)进行组合
type Name = { name:string } type Age = { age:number } type Person = Name & Age
type: 如果对类型别名进行重复定义,typescript会报错。这意味着不能重新定义一个已存在的type
type A = { x: string };
type A = { y: string }; // 错误: 重复定义
三、声明合并
接口:支持。
类型别名:不支持
四、继承与交叉类型
接口:可以通过 extends关键字继承其它接口或类。
类型别名:可以通过 & 符号创建交叉类型,以组合现有的多种类型
参考:
TypeScript 中的 type 和 interface:你真的了解它们的不同吗? - 掘金 (juejin.cn)