理清 TypeScript 的 interface 与 type 的区别

1,219 阅读2分钟

官方描述

Type aliases and interfaces are very similar, and in many cases you can choose between them freely. Almost all features of an interface are available in type, the key distinction is that a type cannot be re-opened to add new properties vs an interface which is always extendable.

从上面这段话中我们可以得知:

  • 几乎interface的所有特性都可以用type实现
  • interface可以添加新的属性,是可扩展的

区别一

针对第一点,参考官方对interfacetype的描述:

  • Interfaces are basically a way to describe data shapes, for example, an object.
  • Type is a definition of a type of data, for example, a union, primitive, intersection, tuple, or any other type.

interface用来描述数据的形状(data shapes)

至于什么是数据的形状呢? 例如二叉树中数据以分层的形式排布,每个元素最多由两个子元素;在链表中,数据以链式存储,顺序布局,这便是data shapes,结合数据本身,以及保留data shapes的相关操作(对于链表来说就是对链表节点的添加、删除等,不破坏原有结构),这三者就组成了数据结构。

type是数据类型的定义,如联合类型(A |B)基本类型交叉类型(A&B)、元组等,此外type 语句中还可以使用 typeof获取实例的类型进行赋值。

简而言之,interface右边必须是 data shapes, 而type右边可以是任何类型。

开头提到interface是可扩展的的,也是得益于声明合并,而type虽然通过extends可以达到类似的效果,但谈不上可扩展。官方描述中也提到:

the key distinction is that a type cannot be re-opened to add new properties vs an interface which is always extendable.

区别二

针对第二点,interface支持声明合并(declaration merging),type alias不支持。

interface Person {
  name: string;
}
interface Person {
  age: number;
}
// 合并为:interface Person { name: string age: number}type User = {
  name: string;
};
type User = {
  age: number;
};
// error: Duplicate identifier 'User'.

总结

主要有两点区别:

  1. interface右边只能是data shapes,而type右边涵盖的范围更大,还可以是联合类型(A |B)基本类型交叉类型(A&B)、元组等,也可以使用typeof
  2. interface支持声明合并,type不支持声明合并。

参考

TS Handbook