TypeScript中type和interface的区别
写前端项目时,特别是用React或Vue搭大型应用,TypeScript几乎是标配。但在定义数据结构时,很多人会纠结:到底该用type还是interface?这两个看起来都能描述对象形状,到底有啥不一样?
其实它们大部分时候可以互换,但细节上差别不小,选对了写代码更顺手。
从语法上看区别
先看个简单的例子。假设你要描述一个用户信息,可以用 type:
type User = {
name: string;
age: number;
};也可以用 interface:
interface User {
name: string;
age: number;
}表面看几乎一样。但当你想扩展一个已有类型时,差别就出来了。
接口能被重复声明,类型不行
比如团队开发中,不同人负责不同模块,都可能要给同一个对象加字段。用 interface 可以这么做:
interface User {
name: string;
}
interface User {
age: number;
}TS会自动合并两个同名的interface,最终User就有name和age。这种特性叫“声明合并”,在插件化系统或多人协作时特别实用。
而如果你用 type 声明两次User,直接报错:
type User = { name: string };
type User = { age: number }; // 错误:不能重复声明类型支持更复杂的计算
当你需要做类型运算,比如联合类型、映射类型,type 更灵活。
比如你要定义一个状态,只能是这几个值之一:
type Status = 'idle' | 'loading' | 'success' | 'error';或者从一个对象里挑几个字段:
type PartialUser = { [K in keyof User]?: User[K] };这些操作用 interface 搞不定,它只能描述对象结构,不能做类型推导或组合。
继承和扩展方式不同
两者都能实现扩展,但写法略有差异。
interface用 extends:
interface Person {
name: string;
}
interface Developer extends Person {
skill: string;
}type也能实现类似效果,不过用交叉类型:
type Person = {
name: string;
};
type Developer = Person & {
skill: string;
};功能差不多,但后者在复杂组合时容易让类型变臃肿,调试起来麻烦点。
实际开发中怎么选
如果你在写业务组件,比如表单、用户中心这些,推荐优先用 interface。因为大多数时候你是在描述对象结构,而且未来可能被别人扩展。代码更清晰,也方便团队协作。
当你处理工具类型、条件类型、或者要做类型编程时,就用 type。比如封装一个通用请求响应结构,或者从后端接口自动生成TS类型,这时候 type 的表达能力更强。
公司里有个同事一开始全用 type,后来接口越来越多,发现没法合并声明,改起来到处冲突。换成 interface 主导后,模块之间耦合低了不少。
说白了,interface 像设计图纸,适合公开的、可扩展的结构;type 像加工模具,适合内部做复杂变形。