网站搜索

ecmascript 6 - Typescript 将数组转换为关联数组


我有一个数组,我想将其转换为关联数组,并且需要一些关于语法的帮助。我希望这个关联数组是只读的。

我是 TypeScript 新手,如果这是一个非常基础的问题,请多包涵。

给定一个关联数组的数组:

interface Greeting {
    name: String,
    punctuation?: String,
}

const GreetingArray: ReadonlyArray<Greeting> = [
    {name: "noob", punctuation: "!"},
    {name: "sam", punctuation: "."}
]

我笨拙地用上了 new Map<> 并对元素使用 forEach,但我不确定如何让它与只读 Map 或通用只读关联数组兼容。

我希望能够将我的关联数组数组转换为一个对象,该对象支持类似字典/哈希映射的查找行为,使用 .name 作为键,而完整的关联数组作为对象({"noob": {name: "noob", punctuation: "!"}, "sam": {name: "sam", punctuation: "."}})。

编辑:根据建议删除了令人分心的失败尝试 :)

编辑2:从我的问题中删除更多无用的文字 😅

答案#1

你正在寻找的类型是像

interface GreetingDict {
    readonly [k: string]: Greeting
}

它有一个 string 索引签名,这意味着它可以有任意数量的 string 类型的键,每个键都应该有一个关联的 Greeting 类型的属性。而且它是一个 readonly 索引签名,这意味着编译器会阻止人们对其进行写操作。(注意,它只是阻止这样的写操作,并不保证写操作不会发生;它只是编译时的构造,并且 TypeScript 将 readonly 属性视为可以相互赋值给非 readonly 属性,因此可以很容易地通过使用类型不是 readonly 的引用对同一个对象进行写操作来规避这一限制。)


给定一个像 Greeting 的数组

const greetingArray: ReadonlyArray<Greeting> = [
    { name: "noob", punctuation: "!" },
    { name: "sam", punctuation: "." }
]

你可以通过将它用 map 映射为键值对数组,然后使用 Object.fromEntries() 方法将其转换为单个对象,从而将其转换为 GreetingDict。

const myReadOnly: GreetingDict =
  Object.fromEntries(greetingArray.map(g => [g.name, g]));

你可以验证这是否按预期工作:

console.log(myReadOnly)
/* {
  "noob": {
    "name": "noob",
    "punctuation": "!"
  },
  "sam": {
    "name": "sam",
    "punctuation": "."
  }
}  */

代码的 Playground 链接