typescript 迭代对象更新属性等于字典

63lcw9qa  于 2023-03-13  发布在  TypeScript
关注(0)|答案(2)|浏览(154)

我有以下示例对象

const example = {
  a: "foo",
  b: "bar",
  c: 123,
  d: "1",
  e: "3",
  f: false,
};

我还有另一个类似字典的函数,用于example中的一些属性

const dictionary = {
  d:{
    "1": "good",
    "2": "bad",
    "3": "perfect",
    "4": "terrible",
  },
  e:{
    "1": "big",
    "2": "small",
    "3": "huge",
  },

我需要的是迭代example,查找dictionary中存在的属性,并根据其值更新它,最后我得到了以下代码

example = {
  a: "foo",
  b: "bar",
  c: 123,
  d: "good",
  e: "huge",
  f: false
};

我试过这个

for (const field of Object.keys(dictionary)) {
    if (field in example) {
       Object.assign(example, { [field]: dictionary[field][example[field]] });
    }
}

但我得到了很多索引错误

smdnsysy

smdnsysy1#

const newObject = Object.entries(example).reduce((changedObj, [key, val]) => {
   return { ...changedObj, [key]: dictionary?.[key]?.[val] ?? val }
}, {})

console.log(newObject)
polhcujo

polhcujo2#

您的代码工作正常,但TypeScript抱怨了两次,这是有道理的。
首先它会抱怨dictionary[field],根据field的值,dictionary[field]的类型是具有三个属性的对象或具有四个属性的对象(并且它可能具有更多值)。TypeScript无法检测dictionary[field]的类型(因为可能的值不相交),并决定其类型为any。接下来,example[field]用作dictionary[field]的属性名称,但any没有属性。
它还抱怨example[field],因为同样无法确定其类型。根据field的值,example[field]的类型为numberstringboolean。由于这些类型没有共同点,因此检测到的example[field]的类型也为any,并且不能用作属性名称。
解决办法很简单:声明exampledictionary的类型,以让TypeScript知道您希望从中获得什么。
描述dictionary的类型很容易:

const dictionary: Record<string, Record<string, string>> = {
  ...
};

描述example的类型也很容易...

const example: Record<string, string | number | boolean> = {
  ...
};

...但这并没有停止TypeScript抱怨,它是正确的:example[field]用作dictionary[field]的属性名称,但boolean值不能用作索引;仅允许stringnumber作为属性名称。
解决方案是显式声明any为存储在example中的值的类型:

const example: Record<string, any> = {
  ...
};

这些类型允许TypeScript执行其代码分析。
上网查一下。

相关问题