"面试官问我 type 和 interface 有什么区别,我说都能描述对象,然后就没有然后了......"
前言
刚开始接触 TypeScript 的时候,我一直搞不清 type 和 interface 到底有什么本质区别------反正写对象类型两个都能用,那我随便选一个不就行了?
后来被面试官问了几次,又踩了几个坑,才搞明白:它俩 80% 的场景能互换,剩下 20% 的差异才是关键。这篇文章我把这些差别整理成 4 个考点,每个都有代码、有对比、有速查表,看完面试直接背。
你将会收获:
- 🎯 type 和 interface 的 4 大核心区别,面试问到对答如流
- 🔧 每个区别配有可运行代码,粘贴即用
- 📦 React 组件 Props 的最佳实践
- 📊 终极速查表 + 口诀,考前扫一眼就够了
技术栈:TypeScript、React。
一、用大白话讲:type 和 interface 是什么?
给 JS 数据"定规矩"有两种写法:
ts
// 方式一:interface
interface User {
name: string;
age: number;
avatarUrl: string;
}
// 方式二:type
type UserType = {
name: string;
age: number;
avatarUrl: string;
}
用起来一模一样:
ts
const u1: User = { name: 'Hjf20', age: 18, avatarUrl: 'https://vitejs.dev/logo.svg' };
const u2: UserType = { name: 'Hjf20', age: 18, avatarUrl: 'https://vitejs.dev/logo.svg' };
大白话解释
| 概念 | 一句人话 | 出身 |
|---|---|---|
interface |
一份"合同"------你得按我的格式来 | OOP 体系亲儿子,class extends implements 的原配 |
type |
一个"别名"------给任意类型贴个标签 | 类型系统的瑞士军刀,啥都能表示 |
💡 共同点:函数参数、返回值、变量约束,它俩都能干。下面说区别。
二、区别① ------ 继承方式不同
这是最高频考点。interface 用 extends(继承) ,type 用 &(交叉类型)。
ts
// ===== interface:extends 继承,子承父业 =====
interface Person {
name: string;
}
// 不从零开始,基于 Person 扩展
interface Employee extends Person {
job: string;
}
// ===== type:& 交叉类型,拼积木 =====
type PersonType = { name: string };
type EmployeeType = PersonType & { job: string };
const e1: Employee = { name: '胡椒粉', job: '字节agent开发工程师' };
const e2: EmployeeType = { name: '黄敬峰', job: '大厂的苗子' };
思维模式对比
| 写法 | 关键字 | 思路 | 类比 |
|---|---|---|---|
interface A extends B |
extends |
A 是 B 的扩展版 | 继承家业 |
type A = B & { ... } |
& |
把多个类型拼成新类型 | 拼乐高 |
💡 一句话记住:interface 像"继承家业",type 像"拼乐高"。
三、区别② ------ 声明合并(interface 独有,面试必问)
这是 interface 的杀手锏,type 做不到。
ts
// ===== interface:同名自动合并 ✅ =====
interface Animal {
name: string;
}
// 接口属性可以分头多次约束,自动合并
interface Animal {
age: number;
}
const dog: Animal = { name: '三寸钉', age: 1 }; // ✅ 两个字段都要有
// ===== type:同名直接报错 ❌ =====
type AnimalType = { name: string };
type AnimalType = { age: number }; // ❌ 报错:标识符重复
这个能力有什么用?
TS 设计声明合并,是为了让你不修改源码就能扩展第三方库的类型:
ts
// node_modules 里某个库的类型
interface Window {
appVersion: string;
}
// 你的代码里直接扩展
interface Window {
myCustomProp: number; // 自动合并,Window 类型现在多了一个字段
}
⚠️ 面试考点:"type 和 interface 最核心的区别是什么?" ------ 优先答声明合并。interface 同名自动合并,type 同名报错。
四、区别③ ------ 非对象类型(type 独有)
interface 只能描述对象形状。type 什么都能表示:
ts
// ✅ type 可以表示这些------interface 全做不到
type ID = string | number; // 联合类型
type Point = [number, number]; // 元组类型
// ❌ interface 只能描述对象结构
// interface ID = string | number; // 语法错误
能力边界一览
| 能力 | interface | type |
|---|---|---|
| 描述对象结构 | ✅ | ✅ |
| 联合类型 `string | number` | ❌ |
元组类型 [number, number] |
❌ | ✅ |
原始类型别名 type Age = number |
❌ | ✅ |
💡 一句话记住:interface 只能"画对象的形状",type 可以"给任何类型贴标签"。
五、区别④ ------ 函数类型
两者都能描述函数签名,写法不同:
ts
// ===== interface 写法:调用签名 =====
interface AddFn {
(a: number, b: number): number;
}
const add1: AddFn = (x, y) => x + y;
add1(1, 2);
// ===== type 写法:箭头函数,一行搞定 =====
type AddType = (a: number, b: number) => number;
| 维度 | interface 调用签名 | type 箭头写法 |
|---|---|---|
| 可读性 | 还行 | 更直观 |
| 代码量 | 多几行 | 一行搞定 |
| 结论 | 能用 | 更方便 |
六、实战:React 组件 Props 用什么?
interface 出身 OOP 体系,和 class、extends、implements 是原配。React 父子组件间的"数据合同",天然适合 interface:
tsx
// 接口,传统OOP 核心概念
// TS 大型企业级开发强类型语言,类Java的类型系统
// 面向接口的编程 ------ 父子组件数据接口
interface User {
name: string;
age: number;
avatarUrl: string;
}
interface UserCardProps {
user: User;
onEdit(id: number): void; // 函数签名
}
const UserCard: FC<UserCardProps> = ({ user, onEdit }) => {
return <>{/* 组件内容 */}</>;
};
export default UserCard;
💡 实践建议 :定义对象/组件 Props 用 interface,定义工具类型/联合类型用 type。这是社区主流习惯,团队协作时直接这么干就行。
七、终极速查表
| 维度 | interface | type |
|---|---|---|
| 描述对象 | ✅ | ✅ |
| 继承/扩展 | extends(继承) |
&(交叉) |
| 同名声明合并 | ✅ 自动合并 | ❌ 直接报错 |
| 表示非对象类型 | ❌ | ✅(联合、元组、原始类型) |
| 函数类型 | 调用签名写法 | 箭头写法更简洁 |
| 适用场景 | OOP、React Props、类型扩展 | 工具类型、联合类型、灵活组合 |
面试一句流
"对象用 interface,联合用 type;要合并用 interface,要灵活用 type。"
结尾
type 和 interface 的区别看着简单,但每个点都能深入问。希望这篇文章帮你把 4 个考点理清楚了。
源码在 hjf-ai/interview/ts/type_interface/ 目录下。有问题欢迎评论区交流,祝面试顺利 🔥
写于 2026 年 8 月 · TypeScript 面试备战