文章目录

TypeScript 类型定义:interface 与 type alias

发布于 2026-04-11 06:12:50 · 浏览 9 次 · 评论 0 条

TypeScript 类型定义:interface 与 type alias

TypeScript 提供了两种主要的方式来定义类型:interface(接口)和 type alias(类型别名)。虽然两者在许多情况下可以互换使用,但在处理复杂的类型结构时,它们各有独特的行为。理解这些差异能帮助你写出更健壮、更易维护的代码。


1. 基础对象定义

对于定义简单的对象结构,两者的语法非常相似,功能也几乎一致。

定义一个包含 nameage 的用户对象。

使用 interface

interface User {
  name: string;
  age: number;
}

使用 type

type User = {
  name: string;
  age: number;
};

在这两种情况下,声明一个变量并赋值的效果完全相同。

const user1: User = { name: "Alice", age: 25 };

2. 类型别名的独有能力

type alias 的能力范围比 interface 更广,它可以用于定义原始类型、联合类型、元组等非对象结构。

2.1 定义联合类型

当你需要表示一个值可以是多种类型之一时,使用 type

定义一个 ID 类型,它可以是字符串或数字。

type ID = string | number;

const userId: ID = "abc-123";
const productId: ID = 98765;

2.2 定义元组类型

当你需要表示一个已知长度和类型的数组时,使用 type

定义一个坐标类型,包含两个数字。

type Coordinate = [number, number];

const location: Coordinate = [10.5, 20.3];

2.3 映射类型

在构建工具类型时,通常使用 type 结合 keyof

创建一个将所有属性变为可选的类型工具。

type PartialUser = {
  [K in keyof User]?: User[K];
};

3. 接口的独有能力

interface 最核心的特性是“声明合并”。这意味着如果定义了多个同名接口,TypeScript 会自动将它们合并为一个接口。

3.1 声明合并

这在扩展第三方库的类型时非常有用。

定义一个 Window 接口包含 title 属性。

interface Window {
  title: string;
}

再次定义一个 Window 接口包含 version 属性。

interface Window {
  version: string;
}

此时,Window 类型将同时包含 titleversion

const windowProps: Window = {
  title: "My App",
  version: "1.0.0"
};

如果尝试使用 type 进行同名定义,TypeScript 会抛出错误:Duplicate identifier 'Window'


4. 继承与扩展

两者都支持继承,但语法略有不同。

4.1 Interface 继承 Interface

使用 extends 关键字。

interface Animal {
  name: string;
}

interface Bear extends Animal {
  honey: boolean;
}

4.2 Type 继承 Type

使用交叉类型 &

type Animal = {
  name: string;
};

type Bear = Animal & {
  honey: boolean;
};

4.3 Interface 继承 Type

接口可以继承类型别名。

type Animal = {
  name: string;
};

interface Bear extends Animal {
  honey: boolean;
}

4.4 Type 继承 Interface

类型别名也可以继承接口,同样使用交叉类型 &

interface Animal {
  name: string;
}

type Bear = Animal & {
  honey: boolean;
};

5. 决策指南

在实际开发中,选择哪一个主要取决于你的具体需求。下表总结了关键区别与选择依据。

特性 Interface Type Alias
定义对象 支持 支持
定义联合类型 (A \| B) 不支持 支持
定义元组 ([A, B]) 不支持 支持
声明合并 (同名合并) 支持 不支持
扩展方式 extends 交叉类型 &
适用场景 定义对象模型、库的 API 定义 定义联合类型、工具类型、复杂类型组合

6. 快速选择流程

为了在编码时快速做出判断,可以参考以下决策流程。

graph TD A[Start: Need to define a type] --> B{What is the data type?} B -->|Primitive / Union / Tuple| C[Use Type Alias] B -->|Object / Function| D{Needs declaration merging?} D -->|Yes| E[Use Interface] D -->|No| F{Is it a complex type mapping?} F -->|Yes| C F -->|No| G{Team coding style preference} G -->|Interface style| E G -->|Type style| C

解读流程图

  1. 检查数据类型。如果是基本类型、联合类型(string | number)或元组,直接使用 type
  2. 如果是对象或函数,判断是否需要“声明合并”。如果你需要多次定义同名类型来扩展它(例如给 window 对象挂载属性),必须使用 interface
  3. 如果不需要合并,判断是否涉及复杂的映射类型(如 Pick<T, K>、泛型工具)。通常这些场景下 type 更灵活。
  4. 如果以上都不涉及,遵循团队或项目的统一代码风格。在纯面向对象编程中,interface 是传统选择;在函数式编程或 React 组件 Props 定义中,type 非常流行。

评论 (0)

暂无评论,快来抢沙发吧!

扫一扫,手机查看

扫描上方二维码,在手机上查看本文