深入理解 interface vs type:终结之争

📝 引言

📌 场景/痛点

在面试或代码评审中,你一定见过这样的争论:

同事 A :"这里应该用 interface,因为这是面向对象的写法。"
同事 B :"不,这里应该用 type,因为 type 更灵活,能写联合类型。"

作为新手,面对功能上极其相似的两者,往往陷入"选择困难症"。混用 interfacetype 会让代码风格支离破碎,增加维护成本。在 TypeScript 的今天,我们其实已经有了非常明确的标准答案。

✨ 最终效果

读完本文,你将拥有一个清晰的"决策树",无论遇到什么场景,都能在 1 秒钟内决定是用 interface 还是 type

📖 内容概览

我们将从以下维度彻底厘清两者的关系:

  1. 共同点:定义对象形状时几乎一样。
  2. 核心差异 :声明合并 (interface 独有) vs 灵活表达 (type 独有)。
  3. 扩展能力:它们能否互相继承?
  4. 2026 开发标准:到底该听谁的?

🛠️ 正文

1. 环境准备

不需要任何特殊环境,直接在 src/ 下新建 definitions.ts 即可。这是一个纯"脑力体操"章节。

2. 共同点:定义对象形状

在 90% 的简单场景下,定义一个对象的结构,两者几乎没有区别

typescript 复制代码
// 写法 A:Interface
interface UserI {
    id: number;
    name: string;
}

// 写法 B:Type Alias
type UserT = {
    id: number;
    name: string;
};

const u1: UserI = { id: 1, name: "A" };
const u2: UserT = { id: 2, name: "B" };

结论:单纯描述数据结构时,看你心情。

3. 核心差异一:声明合并

这是 interface 的"独门绝技"。如果你定义了两个同名 interface,它们会自动合并成一个。而 type 不允许重复定义。

typescript 复制代码
// ✅ Interface 自动合并
interface Window {
    title: string;
}

interface Window {
    // 此时 Window 已经有了 title,现在添加 version
    version: string;
}

// 最终 Window 包含:title, version
const w: Window = { title: "TS", version: "5.9" };
typescript 复制代码
// ❌ Type 报错:重复标识符 'Window'
type Window = {
    title: string;
};

type Window = { // Error: Duplicate identifier 'Window'.
    version: string;
};

为什么要合并?

这在扩展第三方库 时非常有用。例如你想给 Window 对象加一个自定义属性,或者给 axios 添加拦截器类型定义,用 interface 声明合并是最优雅的方案。

4. 核心差异二:灵活表达

这是 type 的"绝对统治区"。interface 只能定义对象结构,而 type 可以定义任何类型的别名。

typescript 复制代码
// 1. 联合类型
type ID = string | number; // interface 无法实现

// 2. 元组类型
type Coord = [number, number]; // interface 无法实现

// 3. 映射类型
type ReadonlyUser = {
    readonly [K in keyof UserT]: UserT[K]
}; // interface 无法直接实现这种映射

结论 :只要涉及到非对象的复杂类型(联合、元组、函数签名、映射),必须用 type

5. 互相继承:谁兼容谁?

好消息是,它们是可以混用的。

  • interface 可以 extends type
  • type (交叉) 也可以 extends (通过 & 或条件类型) interface
typescript 复制代码
type Animal = {
    name: string;
};

// interface 继承 type
interface Dog extends Animal {
    bark(): void;
}

// type 继承 interface
interface Cat {
    meow(): void;
}

type MyCat = Cat & { color: string };

❓ 常见问题

Q1: 听说 interface 编译后性能更好?

A: 在几年前的 TS 版本中,interface 的处理速度确实略快于 type 的处理速度,尤其是在处理数百万个类型的大项目中。但在 TypeScript 5.9 中,编译器经过了大量性能优化,两者的性能差异在绝大多数项目中已经可以忽略不计。不要为了微乎其微的性能差异牺牲代码的可读性和灵活性。

Q2: React 组件的 Props 用哪个?

A: 2026 年的标准答案:统一用 type

typescript 复制代码
// ✅ 推荐
type ButtonProps = {
    label: string;
    onClick: () => void;
    disabled?: boolean;
};

export const Button = ({ label, onClick }: ButtonProps) => { ... };

原因:React 组件的 Props 经常会出现联合类型(如 variant: "primary" | "secondary"),type 处理这个更自然。

Q3: 我到底该选哪个?给个准话!

A: 遵循 "Default to Type"(默认用 Type)原则。

  • 95% 的情况 :使用 type。它更全能,更符合函数式编程的组合思想。
  • 5% 的情况 :使用 interface
    • 当你需要声明合并来扩展第三方库类型时。
    • 当你定义一个类 (Class) 必须遵循的形状时(虽然 Class 也可以 implement Type,但 OOP 习惯上用 interface)。

🎯 总结

这场争论没有输赢,只有最适合的场景。本文我们确立了 2026 年的 TS 编码规范:

  1. 日常开发 :优先使用 type,它支持联合、交叉、映射,功能更强大。
  2. 库开发/扩展 :利用 interface 的声明合并特性,对原有类型进行补丁式扩展。
  3. 风格统一 :不要在一个文件里混用 typeinterface 定义同一个概念,保持团队规范一致。

🚀 下期预告:

既然决定了用 type,那如何利用 type 打造更强大的工具?比如"把所有属性变成只读"或者"提取所有 Key"?

下一篇文章我们将深入 《映射类型与只读范式》,掌握代码生成的核心魔法。

💬 互动环节:

你现在团队里的代码规范是偏向 interface 还是 type?看完本文是不是打算重构一下了?

如果觉得文章帮你解决了困惑,请点赞👍、收藏⭐、关注👀,下期更精彩!

相关推荐
css趣多多2 小时前
vue环境变量
前端
RFCEO2 小时前
前端编程 课程十五、:CSS核心基础3:文字+段落样式
前端·css·文字+段落样式·css文本样式·美化页面文本内容·演示动画说明·单行文字垂直居中技
摇滚侠2 小时前
【程序员入门系列】jQuery 零基础入门到精通!Jquery 选择器 API
前端·javascript·jquery
源力祁老师2 小时前
深入解析 Odoo 中 default_get 方法的功能
java·服务器·前端
阿蒙Amon3 小时前
TypeScript学习-第11章:配置文件(tsconfig.json)
学习·typescript·json
sleeppingfrog3 小时前
zebra打印机实现前端打印
前端
摇滚侠3 小时前
前端判断不等于 undefined 不等于 null 的方法
前端
DFT计算杂谈3 小时前
VASP+Wannier90 计算位移电流和二次谐波SHG
java·服务器·前端·python·算法
止观止3 小时前
告别 require!TypeScript 5.9 与 Node.js 20+ 的 ESM 互操作指南
javascript·typescript·node.js