TypeScript 接口和类型别名区别
在前端开发里,大家常会用 TypeScript 给代码“上保险”——避免变量传错类型、函数参数乱填格式。但刚学的人常会搞混接口和类型别名这两个工具,总觉得它们都是用来定义类型的,到底啥时候用哪个?
先搞懂:它们本质都是“类型契约”
不管是接口(interface)还是类型别名(type alias),核心作用都是给一段代码约定“必须是什么样子”,就像你订外卖时填的收货地址,必须有省市区、门牌号,少一样都送不到。举个例子,要定义一个“人”的类型,用接口写是这样:

`typescript
interface Person { name: string; age: number }
`
用类型别名写也差不多:
`typescript
type Person = { name: string; age: number }
`
这俩现在看起来没区别,就像你买奶茶选“去冰”,堂食和小程序点单都能实现,只是操作方式不同而已。
第一个关键区别:能不能“扩展开”
日常开发里,经常需要在原有类型上加新功能,这时候接口和类型别名的扩展方式完全不一样。
接口用的是“声明合并”——就像你买奶茶时跟老板说“加珍珠”,之后又说“加椰果”,老板会自动把要求合并,接口的同名定义也会自动合并。比如:
`typescript
interface User { id: number }
interface User { name: string } // 会自动合并成 User 有 id 和 name
`
这种场景特别适合写插件扩展,比如你用了一个UI库,想给它的全局配置加自定义字段,用接口改就很方便。
而类型别名用的是“扩展继承”——得用&符号把多个类型拼起来,就像你买奶茶时选“去冰+三分糖+加珍珠”,得把所有要求列在一起。同样定义一个带两个字段的User:
`typescript
type User = { id: number } & { name: string }
`
这种方式更适合“组合不同类型”,比如你要把“员工”和“管理员”的类型拼出“高级管理员”,用类型别名会更直观。
第二个关键区别:能定义的“类型范围”
就像你用外卖小程序,接口只能点“餐品”(对象、类的结构这类),而类型别名能点“餐品+饮品+配件”——它支持更灵活的类型组合。
比如你要定义“一个值要么是字符串,要么是数字”,这种“联合类型”只能用类型别名:
`typescript
type StringOrNumber = string | number;
`
要是用接口写,就会报错,因为接口本质是用来约定“对象形状”的。再比如,你要定义“一个对象里的属性必须是布尔值”(索引类型),也只能用类型别名:
`typescript
type BooleanMap = { [key: string]: boolean };
`
这种灵活度是接口比不了的,就像你买奶茶除了基础餐品,还能单独加配料、选甜度,而接口只能按固定套餐选。
最后给个实用选择建议
总结下来,不用纠结哪个“更好”,选对场景就行:
- 如果是定义对象、类的结构,或者需要扩展(比如插件里改全局类型),优先用接口;
- 如果需要定义联合类型、索引类型,或者要组合多个类型,就用类型别名。
举个实际开发的例子:做电商系统时,用户的基础信息用接口定义,方便后续加“会员等级”“收货地址”等扩展字段;而商品的状态(上架/下架/待售)这种联合类型,就用类型别名来写,一目了然。