TypeScript 必考题:type 和 interface 的区别一次搞懂

9 阅读5分钟

"面试官问我 type 和 interface 有什么区别,我说都能描述对象,然后就没有然后了……"

前言

刚开始接触 TypeScript 的时候,我一直搞不清 typeinterface 到底有什么本质区别——反正写对象类型两个都能用,那我随便选一个不就行了?

后来被面试官问了几次,又踩了几个坑,才搞明白:它俩 80% 的场景能互换,剩下 20% 的差异才是关键。这篇文章我把这些差别整理成 4 个考点,每个都有代码、有对比、有速查表,看完面试直接背。

你将会收获

  • 🎯 type 和 interface 的 4 大核心区别,面试问到对答如流
  • 🔧 每个区别配有可运行代码,粘贴即用
  • 📦 React 组件 Props 的最佳实践
  • 📊 终极速查表 + 口诀,考前扫一眼就够了

技术栈:TypeScript、React。

一、用大白话讲:type 和 interface 是什么?

给 JS 数据"定规矩"有两种写法:

// 方式一:interface
interface User {
  name: string;
  age: number;
  avatarUrl: string;
}

// 方式二:type
type UserType = {
  name: string;
  age: number;
  avatarUrl: string;
}

用起来一模一样:

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 用 &(交叉类型)

// ===== 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 BextendsA 是 B 的扩展版继承家业
type A = B & { ... }&把多个类型拼成新类型拼乐高

💡 一句话记住:interface 像"继承家业",type 像"拼乐高"。

三、区别② —— 声明合并(interface 独有,面试必问)

这是 interface 的杀手锏,type 做不到。

// ===== 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 设计声明合并,是为了让你不修改源码就能扩展第三方库的类型

// node_modules 里某个库的类型
interface Window {
  appVersion: string;
}
// 你的代码里直接扩展
interface Window {
  myCustomProp: number;  // 自动合并,Window 类型现在多了一个字段
}

⚠️ 面试考点:"type 和 interface 最核心的区别是什么?" —— 优先答声明合并。interface 同名自动合并,type 同名报错。

四、区别③ —— 非对象类型(type 独有)

interface 只能描述对象形状。type 什么都能表示:

// ✅ type 可以表示这些——interface 全做不到
type ID = string | number;           // 联合类型
type Point = [number, number];       // 元组类型

// ❌ interface 只能描述对象结构
// interface ID = string | number;   // 语法错误

能力边界一览

能力interfacetype
描述对象结构
联合类型 string | number
元组类型 [number, number]
原始类型别名 type Age = number

💡 一句话记住:interface 只能"画对象的形状",type 可以"给任何类型贴标签"。

五、区别④ —— 函数类型

两者都能描述函数签名,写法不同:

// ===== 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 体系,和 classextendsimplements 是原配。React 父子组件间的"数据合同",天然适合 interface:

// 接口,传统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。这是社区主流习惯,团队协作时直接这么干就行。

七、终极速查表

维度interfacetype
描述对象
继承/扩展extends(继承)&(交叉)
同名声明合并✅ 自动合并❌ 直接报错
表示非对象类型✅(联合、元组、原始类型)
函数类型调用签名写法箭头写法更简洁
适用场景OOP、React Props、类型扩展工具类型、联合类型、灵活组合

面试一句流

"对象用 interface,联合用 type;要合并用 interface,要灵活用 type。"


结尾

type 和 interface 的区别看着简单,但每个点都能深入问。希望这篇文章帮你把 4 个考点理清楚了。

源码在 hjf-ai/interview/ts/type_interface/ 目录下。有问题欢迎评论区交流,祝面试顺利 🔥

写于 2026 年 8 月 · TypeScript 面试备战