TypeScript 必考题:Type 与 Interface 全面对比

TypeScript 必考题:Type 与 Interface 全面对比

在 TypeScript 中,interface 和 type 都是用来定义类型的核心工具------告诉编译器"这个变量应该长什么样"。简单来说:

  • interface (接口)定义的是一个"契约",专注于描述对象的形状(shape):它该有哪些属性、哪些方法,分别是什么类型。
  • type(类型别名)则是给任意类型起一个名字------不限于对象,还可以是基本类型、联合类型、元组、函数签名,甚至是它们的任意组合。

一句话概括:interface 说的是"这个对象必须满足的结构",type 说的是"你可以用这个名字来引用这个类型"。

二者看起来都能描述对象结构,很多人便以为它们可以无脑互换。也正因为如此,type 和 interface 的区别成了 TypeScript 面试中绕不开的高频题。下面就沿着共同点 → 核心差异 → 实践建议这条线,把这道题彻底讲透。


一、共同点:都能描述对象的结构

最基础的用法上,二者几乎一致------描述一个对象的属性结构:

typescript 复制代码
// interface 写法
interface User {
  name: string;
  age: number;
  avatarURL: string;
}

// type 写法
type UserType = {
  name: string;
  age: number;
  avatarURL: string;
};

// 使用方式完全相同
const u1: User = {
  name: "张三",
  age: 18,
  avatarURL: "https://example.com/avatar.jpg",
};

const u2: UserType = {
  name: "李四",
  age: 19,
  avatarURL: "https://example.com/avatar.jpg",
};

无论是 interface 还是 type,编译器都能正确进行类型检查。这也是初学者最容易产生"二者可互换"错觉的地方------但接下来你就会看到,它们的分歧远比共同点多。


二、核心差异

1. 继承方式:extends vs &

当需要基于已有类型扩展出新类型时,两者的语法截然不同:

typescript 复制代码
// interface:使用 extends 继承
interface Person {
  name: string;
}

interface Student extends Person {
  job: string;
}

const s1: Student = {
  name: "张三",
  job: "前端开发",
};

// type:使用 & 交叉类型
type PersonType = { name: string };
type EmployeeType = PersonType & { job: string };

const e1: EmployeeType = {
  name: "李四",
  job: "前端开发",
};

interface 的 extends 带着面向对象"继承"的语义,读起来非常直观。而 type 用 &(交叉类型)来组合,更像是函数式的"拼装"------你可以把任意多个类型合并到一起,灵活性更强。


2. 声明合并:interface 的独门绝技

这是面试官最爱追问的一点。

typescript 复制代码
// interface:两次定义同名接口,会自动合并
interface Animal {
  name: string;
}
interface Animal {
  age: number;
}

const dog: Animal = {
  // 两个 Animal 的成员合并到了一起
  name: "旺财",
  age: 1,
};

// type:两次定义同名类型直接报错!
type AnimalType = { name: string };
type AnimalType = { age: number }; // ❌ 标识符"AnimalType"重复

背后的原因在于,TypeScript 特意为 interface 设计了声明合并(Declaration Merging) 机制。它让你可以在不修改原始代码的前提下,对第三方库或全局类型打"扩展补丁"------比如给 Window 对象追加自定义属性,这在大型项目中相当实用。而 type 作为类型别名,本质上是一个唯一的引用,自然不允许被重复声明。


3. 非对象类型:type 的绝对优势

type 能表达的类型范围远超 interface:

typescript 复制代码
// ✅ 联合类型
type ID = number | string;

// ✅ 元组类型
type Point = [number, number];

// ❌ interface 做不到

当你需要的不是一个单纯的对象形状------比如"可以是数字也可以是字符串"的联合类型,或者固定长度的元组------type 是唯一的选择。interface 天生就是围绕对象结构设计的,它的能力边界也止步于此。


4. 函数类型约束:两种写法,一个效果

二者都能描述函数签名,只是风格不同:

typescript 复制代码
// interface:调用签名
interface AddFn {
  (a: number, b: number): number;
}
const add: AddFn = (a, b) => a + b;
add(1, 2);

// type:箭头函数风格
type AddFnType = (a: number, b: number) => number;
const addType: AddFnType = (a, b) => a + b;
addType(1, 2);

interface 的写法暗示"这是一个可被调用的对象",而 type 的箭头风格更简洁直白。功能上没有高下之分,选择哪种取决于个人和团队的编码偏好。


三、一目了然:总结对比

维度 interface type
描述对象结构 ✅ ✅
继承 / 扩展 extends & 交叉类型
声明合并 ✅ 同名自动合并 ❌ 重复声明报错
联合类型 ❌ ✅
元组类型 ❌ ✅
函数类型 调用签名语法 箭头函数语法
库类型补丁 强(声明合并) 弱

四、实践建议

实际开发中没有绝对的"对"与"错",但社区沉淀出了一些公认的经验:

  • 优先用 interface 描述对象、类、组件 Props------它的语法更聚焦,编译器的错误提示也更清晰。
  • 用 type 处理联合类型、交叉类型、元组、映射类型等 interface 表达不了的场景。
  • 对外暴露的类型 (API、库),首选 interface------方便使用者通过声明合并进行扩展。
  • 比纠结细节更重要的是团队统一风格------选一个规范,然后坚持执行。

把这几个核心差异吃透,TypeScript 这道 type vs interface 的面试题,你就能从容应对了。

相关推荐
环境栈笔记17 小时前
指纹浏览器安卓怎么用?从运行位置到功能验收,先把三种方案分清
前端·人工智能·后端·自动化
计算机魔术师17 小时前
Anthropic IPO 招股文件披露近 9000 亿美元隐性债务
前端
chi113018 小时前
【无标题】
前端·javascript·python
IT_陈寒19 小时前
JavaScript实战技巧总结:深挖数组遍历的性能陷阱与实战解法
前端·人工智能·后端
步行cgn19 小时前
为什么既要 web.xml 又要 springmvc.xml?能不能只配一个?
xml·前端·hive
风骏时光牛马19 小时前
大模型综合能力评测:多维度性能与对齐效果对比
前端
winfredzhang19 小时前
从零手写一个毛玻璃风格的页面搭建台:单文件 HTML 实现组件放置、面板磁吸与图层管理
前端·html
葡萄城技术团队1 天前
1000 人协同压测的环境瓶颈排查:CPU 争用与 Wi\-Fi
前端
excel1 天前
Marked 与 Markdown 有什么区别?该怎么选?
前端
Da Da 泓1 天前
五子棋 Web 端测试用例报告
前端·网络·websocket·网络协议·测试用例·项目