TS 中 interface 和 type 有什么区别

下面这个例子,可以用 type,也可以用 interface。

1
2
3
4
5
6
7
8
9
interface Person {
name: string
age: number
}

const person: Person = {
name: 'lin',
age: 18
}
1
2
3
4
5
6
7
8
9
type Person = {
name: string
age: number
}

const person: Person = {
name: 'lin',
age: 18
}

那 type 和 interface 难道都可以随便用,总得有个区别吧。
TS 文档中说

as

既然如此,那 interface 和 type 应该是不同的东西才对,一个叫接口,一个叫类型别名。只是有时候两者都能实现同样的功能,才会经常被混淆。

interface

interface(接口) 是 TS 设计出来用于定义对象类型的,可以对对象的形状进行描述。

1
2
3
4
5
6
7
8
9
interface Person {
name: string
age: number
}

const person: Person = {
name: 'lin',
age: 18
}

type

type (类型别名),顾名思义,类型别名只是给类型起一个新名字。它并不是一个类型,只是一个别名
就像我们项目中配置 alias,不用写相对路径就能很方便地引入文件
有了 type,我们书写 TS 的时候可以更加方便简洁。

比如下面这个例子,getName 这个函数接收的参数可能是字符串,可能是函数,就可以这么写。

1
2
3
4
5
6
7
8
9
10
11
12
type Name = string
type NameResolver = () => string
type NameOrResolver = Name | NameResolver // 联合类型
function getName(n: NameOrResolver): Name {
if (typeof n === 'string') {
return n
}
else {
return n()
}
}

两者相同点

  • 都可以定义一个对象或函数
1
2
3
4
5
6
7
8
9
type addType = (num1:number,num2:number) => number

interface addType {
(num1:number,num2:number):number
}

const add:addType = (num1, num2) => {
return num1 + num2
}
  • 都允许继承(extends)
1
2
3
4
5
6
7
8
9
10
interface Person {
name: string
}
interface Student extends Person {
grade: number
}
const person:Student = {
name: 'lin',
grade: 100
}
  • type 继承 type
1
2
3
4
type Person = {
name: string
}
type Student = Person & { grade: number } 用交叉类型
  • interface 继承 type
1
2
3
4
5
6
7
type Person = {
name: string
}

interface Student extends Person {
grade: number
}
  • type 继承 interface
1
2
3
4
5
interface Person {
name: string
}

type Student = Person & { grade: number } 用交叉类型

两者不同点

类型别名会给一个类型起个新名字。 类型别名有时和接口很像,但是可以作用于原始值,联合类型,元组以及其它任何你需要手写的类型。 – TS 文档

合并重复声明

1
2
3
4
5
6
7
8
9
10
11
12
13
interface Person {
name: string
}

interface Person { // 重复声明 interface,就合并了
age: number
}

const person: Person = {
name: 'lin',
age: 18
}

重复声明 type ,就报错了

1
2
3
4
5
6
7
8
9
10
11
12
13
type Person = {
name: string
}

type Person = { // Duplicate identifier 'Person'
age: number
}

const person: Person = {
name: 'lin',
age: 18
}

小结

  • interface 和 type 被 TS 设计出来,是完全不同的东西,有各自的职责。
  • interface 是接口,用于描述一个对象。
  • type 是类型别名,用于给各种类型定义别名,让 TS 写起来更简洁、清晰。
  • 只是有时候两者都能实现同样的功能,才会经常被混淆,相信看完本文你能分清他俩了。
  • 平时开发中,一般使用组合或者交叉类型的时候,用 type。
  • 一般要用类的 extends 或 implements 时,用 interface。
  • 其他情况,比如定义一个对象或者函数,就看你心情了。