Skip to content

TypeScript 中 type 和 interface 的区别

摘要:TypeScript 中的 typeinterface 都可以定义类型,但在扩展方式、合并声明、使用场景等方面存在重要区别。本文将详细对比两者的差异,帮助开发者选择合适的类型定义方式。

ts 的 type 和 interface 有什么至关重要的区别吗

概述

TypeScript 中的 typeinterface 都可以用来定义类型,但它们有一些关键区别:

主要区别

  1. 扩展方式不同

    • interface 使用 extends 继承:
      typescript
      interface A { x: number }
      interface B extends A { y: string }
    • type 使用交叉类型 &
      typescript
      type A = { x: number }
      type B = A & { y: string }
  2. 合并声明

    • interface 可以重复声明并自动合并:
      typescript
      interface User { name: string }
      interface User { age: number }
      // 最终 User 为 { name: string; age: number }
    • type 不能重复声明,会报错
  3. 实现类

    • interface 可以被类实现 (implements)
    • type 不能直接被类实现(除非是对象类型或交叉类型)
  4. 灵活性

    • type 可以定义更复杂的类型:
      typescript
      type StringOrNumber = string | number
      type Tuple = [string, number]
      type NonNullable<T> = T extends null | undefined ? never : T

使用建议

  • 使用 interface 当:

    • 需要声明合并
    • 定义对象类型且可能被类实现
    • 与面向对象编程模式配合
  • 使用 type 当:

    • 需要联合类型、元组等复杂类型
    • 需要实用工具类型或条件类型
    • 定义简单类型别名

在大多数情况下,它们可以互换使用,选择主要取决于团队约定和个人偏好。

我说的是至关重要的区别

你问的是至关重要的区别,也就是真正影响开发体验和类型系统能力的核心差异。以下是 TypeScript 中 typeinterface 最关键的区别:


1. 声明合并(Declaration Merging)—— interface 独有

interface 可以重复声明并自动合并,而 type 会报错。

typescript
interface User { name: string }
interface User { age: number }  // ✅ 自动合并成 { name: string; age: number }

type Person = { name: string }
type Person = { age: number }    // ❌ Error: Duplicate identifier 'Person'

为什么至关重要?

  • 这个特性让 interface扩展第三方库类型(如 WindowReact.ComponentProps)时非常有用。
  • type 无法做到这一点,强行扩展只能用 & 交叉类型,但可能导致意外行为。

2. type 能表达更复杂的类型

type 可以定义联合类型、元组、条件类型、映射类型等,而 interface 不能。

typescript
type A = string | number;  // ✅ 联合类型
type B = [string, number]; // ✅ 元组
type C<T> = T extends string ? true : false; // ✅ 条件类型
type D = { [K in "a" | "b"]: boolean };      // ✅ 映射类型

// interface 无法直接表达这些
interface E = string | number;  // ❌ 错误

为什么至关重要?

  • 如果你需要高级类型操作(如 Partial<T>Pick<T, K>Omit<T, K>),必须用 type
  • interface 只能描述对象结构,无法表达逻辑运算。

3. interface 可以被类 implementstype 不行(除非是对象类型)

typescript
interface Animal { name: string; eat(): void }
class Dog implements Animal { name = "Dog"; eat() {} }  // ✅

type AnimalType = { name: string; eat(): void }
class Cat implements AnimalType { name = "Cat"; eat() {} }  // ✅(但仅限于对象类型)

type NotAnObject = string | number;
class Foo implements NotAnObject {}  // ❌ 无法实现联合类型

为什么至关重要?

  • 如果你写 OOP 风格的代码(类 + 接口),interface 更符合传统设计模式。
  • type 只有在描述对象结构时才能被 implements,其他情况(如联合类型)不行。

4. 性能差异(极端情况下)

  • interface 在类型检查时可能更快,因为 TS 会对同名 interface 做合并缓存。
  • type 在复杂类型(如大联合类型)时可能稍慢,因为每次都要重新计算。

为什么至关重要?

  • 超大型项目性能敏感场景下,interface 可能更优(但差异通常很小)。

终极结论:什么时候用哪个?

场景推荐原因
需要扩展第三方类型(如 Windowinterface支持声明合并
需要联合类型、条件类型、映射类型typeinterface 无法表达
类需要 implementsinterface更符合 OOP 习惯
简单的对象类型都可以无本质区别
性能优化(极端情况)interface可能更快

如果只记一点:

  • interface 适合对象结构 + 可扩展性(如 React Props、API 响应类型)。
  • type 适合复杂类型逻辑(如联合类型、工具类型)。