接口和类型别名相似,都可以给类型命名并通过该名字来引用表示的类型。但是它们之间也还存在一些差异。

# 区别一

类型别名能够表示非对象类型,而接口则只能表示对象类型。因此要表示原始类型、联合类型和交叉类型等只能使用类型别名。

type NumberType = number | bigint

# 区别二

接口可以继承其他的接口、类等对象类型,而类型别名不支持继承。

interface Shape {
  name: string
}

interface Circle extends Shape {
  radius: number
}

如果类型别名表示对象类型时,可以借助交叉类型来实现该效果。如:

type Shape = { name: string }
type Circle = Shape & { radius: number }

function bar(circle: Circle) {
  const name = Circle.name
  const radius = Circle.radius
}

# 区别三

接口具有声明合并的行为,而类型别名则不会进行声明合并。

interface A {
  x: number
}
interface A {
  y: number
}

// 合并后
interface A {
  x: number;
  y: number;
}

# 区别四

接口名总是会显示在编译器的诊断信息(如:警告和错误提示)和代码编辑器的智能提示信息,而类型别名的名字只在特定情况下才会显示出来。