TypeScript 中的字典:从混乱到有序(带代码的完整指南)
想象一下,您正在编写一个英语学习应用程序。您需要存储单词的翻译:"cat" → "猫","dog" → "狗"。如何最好地组织这些数据?当然,使用字典(Dictionary)——一种每个键都是唯一的并与一个值相关联的数据结构。
在 JavaScript 中,字典是通过普通对象或 Map 实现的。但 TypeScript 添加了强大的类型系统,将混乱的集合转变为严格、可预测的结构。在本文中,我们将从简单到复杂,详细讲解 TypeScript 中 Dictionary 的声明和初始化。您将学习如何避免常见错误,并编写可预测运行的代码。
什么是 TypeScript 中的 Dictionary?(以及为什么它不仅仅是对象)
在编程中,Dictionary(字典)是一个“键-值”对的集合。在 TypeScript 中,您可以通过三种主要方式创建它:
- 带有索引签名的对象(
{ [key: string]: T }) - Record —— 一个实用类型
- Map —— 内置的 ES6 类
每种方法都有其优点和细微差别。让我们通过实际示例来逐一分析。
方法 1:带有索引签名的经典对象
在 TypeScript 中声明字典最流行的方法是使用 索引签名。这告诉编译器:“该对象可以具有任意数量的属性,其键为特定类型”。
// 声明一个字典类型,其中键为字符串,值为数字interface DictionaryNumber { [key: string]: number;}
// 初始化const ages: DictionaryNumber = { "Anna": 25, "Peter": 30, "Elena": 28};
// 添加新元素ages["Olga"] = 35;
console.log(ages["Anna"]); // 25重要提示: TypeScript 要求所有值都符合声明的类型。尝试添加字符串将导致编译错误:
// 错误!类型 'string' 不能分配给类型 'number'ages["Olga"] = "thirty five";何时使用此方法?
- 当需要一个简单快速的字典时
- 当键是字符串或数字时
- 用于小型集合(最多 1000 个元素)
方法 2:Record —— 优雅的语法
TypeScript 提供了一个内置的实用类型 Record<K, V>。它创建一个对象类型,其中所有键的类型为 K,值的类型为 V。
// 在一行中声明和初始化const grades: Record<string, number> = { "数学": 5, "物理": 4, "历史": 5};
// 可以使用枚举作为键enum Subject { Math = "math", Physics = "physics", History = "history"}
const gradesBySubject: Record<Subject, number> = { [Subject.Math]: 5, [Subject.Physics]: 4, [Subject.History]: 5};Record 的优点:
- 简洁的语法
- 良好的可读性
- 支持联合类型作为键
方法 3:Map —— 用于高级场景
ES6 中的 Map 类是一个功能完整的“键-值”集合,具有额外的功能。在 TypeScript 中,通过泛型对其进行类型化:
// 声明 Mapconst userRoles: Map<string, string> = new Map([ ["admin", "管理员"], ["user", "用户"], ["guest", "访客"]]);
// 添加userRoles.set("moderator", "版主");
// 获取console.log(userRoles.get("admin")); // "管理员"
// 检查是否存在if (userRoles.has("user")) { console.log("角色存在");}
// 和