interface 与 type
用 TypeScript 开发前端项目,需要定义一个对象类型时,你是使用interface还是type?
使用interface:
interface User {
name: string;
avatar: string;
level: number;
}使用type:
type User = {
name: string;
avatar: string;
level: number;
}两者效果完全一样,都能达到我们的目的。
那么问题来了,在描述一个对象结构时,两者到底有何区别?我们到底应该使用哪种方式更好呢?
我们先从多个维度来对比一下两者的区别。
继承
interface写法:
interface UserBasic extends User {
email: string;
}type写法:
type UserBasic = {
email: string;
} & User;interface是真正的继承,而type是模拟继承,实则是合并,但是最后达到的效果却是一样的。
然而,interface 不能继承基本类型。
class S extends string {} // 语法报错type则不受影响:
type S = string & number & {};扩展
interface写法:
interface User {
email: string;
}
interface User {
phone: number;
}interface定义的相同名称的类型,会自动合并;type不能定义相同的名称,会直接报错。
这种用法在扩展第三方库/内置类型时非常有用。
比如,给Array扩展一个自定义方法:
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 实现
在面向对象开发时,我们分别使用interface和type来定义两个接口,看它们是否支持 class 实现。
interface写法:
interface IUser {
name?: string;
age: number;
isAdult(): boolean;
}
class User implements IUser {
age = 16;
isAdult() {
return this.age >= 18;
}
}type写法:
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:
type IUser = {
name?: string;
age: number;
isAdult(): boolean;
}其实就是将后面匿名的对象类型取了一个别名叫做IUser,方便重复使用,如果只用一次完全可以不需要名称。
你也可以看作是这样的:
interface User {
name?: string;
age: number;
isAdult(): boolean;
}
type IUser = User;而interface则不同,它是定义一个有名称对象类型的更“标准”写法。
使用哪个?
大多数时候,你都可以根据自己或团队的习惯任意选择一个来使用都可以,只需记住它们的关键区别即可。
不过使用type也有一个小小的优势,鼠标放上去,编辑器会自动展开显示它的内部结构。

interface则只会展示名称。

如果你还是犹豫不定的话,那么也可以优先使用interface,直到需要type时再使用它。
感谢阅读
大佬们,点个“关注”再走呗~
👇️👇️👇️