跳转到内容

interface 与 type

用 TypeScript 开发前端项目,需要定义一个对象类型时,你是使用interface还是type

使用interface

ts
interface User {
  name: string;
  avatar: string;
  level: number;
}

使用type

ts
type User = {
  name: string;
  avatar: string;
  level: number;
}

两者效果完全一样,都能达到我们的目的。

那么问题来了,在描述一个对象结构时,两者到底有何区别?我们到底应该使用哪种方式更好呢?

我们先从多个维度来对比一下两者的区别。

继承

interface写法:

ts
interface UserBasic extends User {
  email: string;
}

type写法:

ts
type UserBasic = {
  email: string;
} & User;

interface是真正的继承,而type是模拟继承,实则是合并,但是最后达到的效果却是一样的。

然而,interface 不能继承基本类型

ts
class S extends string {} // 语法报错

type则不受影响:

ts
type S = string & number & {};

扩展

interface写法:

ts
interface User {
  email: string;
}

interface User {
  phone: number;
}

interface定义的相同名称的类型,会自动合并;type不能定义相同的名称,会直接报错。

这种用法在扩展第三方库/内置类型时非常有用。

比如,给Array扩展一个自定义方法:

ts
interface Array<T> {
  last(): T | undefined;
}

Array.prototype.last = function() {
  return this[this.length - 1];
};

const arr = [1, 2, 3];
console.log(arr.last());

class 实现

在面向对象开发时,我们分别使用interfacetype来定义两个接口,看它们是否支持 class 实现。

interface写法:

ts
interface IUser {
  name?: string;
  age: number;
  isAdult(): boolean;
}

class User implements IUser {
  age = 16;
  isAdult() {
    return this.age >= 18;
  }
}

type写法:

ts
type IUser = {
  name?: string;
  age: number;
  isAdult(): boolean;
}

class User implements IUser {
  age = 16;
  isAdult() {
    return this.age >= 18;
  }
}

两种写法都完全支持!

关键区别

总结一下上面的几点,你会发现:

📌 关键区别:

type除了不能扩展同名类型,其他好像都能完全替代interface

本质区别

回到type本身的定义,type 其实就是给其他类型取别名的

所以type不仅支持对象类型,还支持为基本类型、联合类型、数组类型、函数类型等各种类型取别名。

比如上面定义的IUser

ts
type IUser = {
  name?: string;
  age: number;
  isAdult(): boolean;
}

其实就是将后面匿名的对象类型取了一个别名叫做IUser,方便重复使用,如果只用一次完全可以不需要名称。

你也可以看作是这样的:

ts
interface User {
  name?: string;
  age: number;
  isAdult(): boolean;
}

type IUser = User;

interface则不同,它是定义一个有名称对象类型的更“标准”写法。

使用哪个?

大多数时候,你都可以根据自己或团队的习惯任意选择一个来使用都可以,只需记住它们的关键区别即可。

不过使用type也有一个小小的优势,鼠标放上去,编辑器会自动展开显示它的内部结构

interface则只会展示名称。

如果你还是犹豫不定的话,那么也可以优先使用interface,直到需要type时再使用它。

感谢阅读

大佬们,点个“关注”再走呗~

👇️👇️👇️