返回文章列表

文章

关于TypeScript中的type、interface 和 Record 

目录
  1. 在 TypeScript 中,type、interface 和 Record 都可用于定义对象类型,但它们在设计目的、功能和使用场景上有显著区别:
  2. 1. interface
  3. 2. type****(类型别名)
  4. 3. Record<Keys, Type>
  5. 关键区别总结
  6. 何时使用?
  7. 示例对比

在 TypeScript 中,typeinterfaceRecord 都可用于定义对象类型,但它们在设计目的、功能和使用场景上有显著区别:#

1. interface#

核心特点

  • 专为对象形状(Object Shape) 设计
  • 支持声明合并(同名接口自动合并)
  • 支持继承extends关键字)
  • 与类(class)实现天然协作(implements使用场景
interface User {
  id: number;
  name: string;
}

// 声明合并(扩展属性)
interface User {
  email: string;
}

// 继承
interface Admin extends User {
  role: "admin";
}

// 类实现
class UserAccount implements User {
  id = 1;
  name = "Alice";
  email = "alice@example.com";
}

适用场景

  • 定义应用核心对象结构(如 API 响应、状态管理)
  • 需要扩展或合并定义的场景
  • 类实例的类型约束

2. type****(类型别名)#

核心特点

  • 可定义任意类型(对象、联合、元组、原始类型等)
  • 支持复杂类型操作(联合 |、交叉 &、条件类型等)
  • 不支持声明合并
  • 不可被类implements(需使用对象形式) 使用场景
// 对象类型
type Point = { x: number; y: number };

// 联合类型
type ID = string | number;

// 元组类型
type Data = [string, number];

// 交叉类型(组合多个类型)
type AdminUser = User & { permissions: string[] };

适用场景

  • 组合复杂类型(联合、交叉)
  • 定义工具类型、泛型操作
  • 需要直接引用原始类型(如type ID = number

3. Record<Keys, Type>#

核心特点

  • TypeScript 内置的工具类型
  • 专门定义键值映射对象
  • 语法:Record<K, T> = { [key in K]: T } 使用场景
// 键为string,值为number
type Scores = Record<string, number>;
// 等价于 { [key: string]: number }

// 使用字面量联合类型约束键
type Weekday = "Mon" | "Tue" | "Wed";
type Schedule = Record<Weekday, string>;
/* 等价于:
{
  Mon: string;
  Tue: string;
  Wed: string;
} */

适用场景

  • 动态键的对象(如字典、映射表)
  • 约束键名的枚举对象
  • 避免手动写索引签名

关键区别总结#

特性interfacetypeRecord<K, T>
本质对象结构声明任意类型的别名内置工具类型
扩展支持继承 (extends)支持交叉类型 (&)需组合其他类型
声明合并✅ 支持❌ 不支持❌ 不支持
类实现implements❌(除非是对象类型)
适用类型对象/函数任意类型(联合、元组等)键值映射对象
动态键需手动添加索引签名需手动添加索引签名✅ 原生支持
典型用途核心业务对象模型类型组合、工具类型字典/枚举映射结构

何时使用?#

  • interface: 定义应用中的核心数据结构(如 UserProduct),尤其需要扩展或类实现时。
  • type
    1. 组合类型(A & BX | Y
    2. 定义元组、函数类型等非对象类型
    3. 创建工具类型(如 Partial<T>
  • Record<K, T>
    1. 键名未知的字典(如 Record<string, boolean>
    2. 键名受限的映射表(如 Record<"status" | "code", number>
    3. 替代手动索引签名(更简洁)

示例对比#

// 等效的对象定义方式:
interface UserMap {
  [id: string]: User;
}

type UserMapType = {
  [id: string]: User;
};

type UserMapRecord = Record<string, User>; // ✅ 最简洁

黄金法则: - 优先用 interface 定义对象(除非需要高级类型操作) - 用 type 处理联合、交叉或工具类型 - 用 Record 处理键值映射结构