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 的面试题,你就能从容应对了。

相关推荐
溪语流沙5 小时前
【Web全栈进阶】前端世界观:现代工具链与框架为什么存在
前端·javascript·vue.js
kyriewen5 小时前
我逐个测了 JSON.stringify 的 7 个坑:第 1 个就在丢数据
前端·javascript·程序员
积流成海6 小时前
用代码实现哈希计算器:Web Crypto API 实战
前端·算法·哈希算法·哈希函数·盘子工具站
data analyse 4566 小时前
服务端访问日志聚合 PV 与 UV 怎么实现?日志采集与口径设计
大数据·前端·数据分析
JavaGuide6 小时前
DeepSeek Harness 重磅更新,Codex、Claude Code 子智能体进官方插件列表了,还有 Git 工作树和思考翻译!
前端·后端
小羊没烦恼!6 小时前
OS X 上使用.NET开发应用程序
开发语言·前端·数据库·人工智能·c#·策略模式
Eiceblue7 小时前
使用 Python 实现 Excel 行列转置(保留单元格样式)
前端·python·excel
西西学代码7 小时前
像素和颜色之间的转换(Flutter)
前端·javascript·flutter
茶底世界之下7 小时前
羽毛颜色已经很鲜艳,还要继续加色吗?用 Awaking 试一次减饱和
前端·ios·运营
风早爽太8 小时前
Mac 搭建 Vue 开发环境
前端·vue.js