当您需要在 TypeScript 中存储键值对集合时,两个常用的选项是Record和Map。它们的用途相似——都将键映射到值——但在语法、功能和用例方面有所不同。了解这些差异有助于您选择合适的工具来完成工作。
- 使用带有索引签名的普通对象 传统上,JavaScript 对象被用作字典:
interface User { id: string; name: string; }
type Users = { [key: string]: User };
const users: Users = { abc123: { id: 'abc123', name: 'John Doe' }, xyz789: { id: 'xyz789', name: 'Jane Doe' }, };
console.log(users['abc123']); // { id: 'abc123', name: 'John Doe' } 该{ [key: string]: User }语法称为索引签名。它告诉 TypeScriptusers可以有任意数量的字符串键,每个键映射到一个User。
- Record<K, T>– 更清晰的类型别名 Record是一种内置的 TypeScript 实用程序类型,它使上述模式更加简洁:
interface User { id: string; name: string; }
type Users = Record<string, User>;
const users: Users = { abc123: { id: 'abc123', name: 'John Doe' }, xyz789: { id: 'xyz789', name: 'Jane Doe' }, }; 优点Record:
比索引签名更短、更易阅读。 如果您想要一个固定的集合,可以限制键: type Roles = Record<'admin' | 'editor', User>; 非常适合纯 JSON 类对象,其中键是编译时已知的字符串(或数字/符号)。 限制:
键始终是字符串(或字符串文字的联合)。 诸如.size或有序迭代之类的方法不是内置的——您可以将其视为普通对象。 3. Map<K, V>– 功能齐全的键值存储 ECMAScriptMap是一个比普通对象提供更多灵活性的类:
interface User { id: string; name: string; }
const usersMap = new Map<string, User>();
usersMap.set('abc123', { id: 'abc123', name: 'John Doe' }); usersMap.set('xyz789', { id: 'xyz789', name: 'Jane Doe' });
console.log(usersMap.get('abc123')); // { id: 'abc123', name: 'John Doe' } 优点Map:
键可以是任何值,而不仅仅是字符串(对象、数字、函数等)。 维护插入顺序,这对于迭代很重要。 提供便捷的方法:、、、、、.get和内置迭代器.set。.has.delete.size 权衡:
比普通物体的开销稍微大一些。 不太容易直接序列化为 JSON(JSON.stringify不会自动包含映射条目)。 4.何时使用哪个 设想 更喜欢 静态或类似 JSON 的数据,简单的字符串键 记录 需要任意键类型(对象、数字等) 地图 需要有序迭代或频繁插入/删除 地图 想要轻量级、可序列化的结构 记录 快速回顾 Record<K, V>:用于对象字面量的 TypeScript 实用程序,其中键是字符串或字符串字面量的并集。简洁轻量。 Map<K, V>:具有丰富方法的 ECMAScript 类,支持任何键类型并保留插入顺序。 在它们之间进行选择取决于您的要求:
对于配置数据,缓存简单的 ID 或使用 JSON:(Record或索引签名)是完美的。 对于具有复杂键或大量变异的动态、运行时驱动的集合:Map更适合。 通过了解这些工具,您可以在 TypeScript 中对键值数据进行建模,并在简单性和功能性之间取得适当的平衡。查看更多www.mxwd.cc