打字稿:将属性从一个对象映射到另一个

时间:2020-08-24 13:08:35

标签: typescript

我有以下两种类型和对象。

type TypeA = {
  a: number;
  b: number;
  c: number;
};
type TypeB = {
  d: number;
  e: number;
  c: number;
};
oldObject: { [key: string]: TypeA };

我想将属性从TypeA类型的对象映射到TypeB类型的对象。到目前为止,我已经提出了以下建议。

const newObject: { [key: string]: TypeB } = {};

Object.entries(oldObject).forEach(([key, value]) => {
  newObject[key] = {
    d: value.a,
    e: value.b,
    c: value.c,
  } as TypeB;
});

在打字稿中是否可以使用诸如map或reduce函数之类的方法?我非常希望不必先将{}分配给newObject

2 个答案:

答案 0 :(得分:1)

您可以使用Object.fromEntries

type TypeA = {
    a: number;
    b: number;
    c: number;
};
type TypeB = {
    d: number;
    e: number;
    c: number;
};

declare const oldObject: { [key: string]: TypeA };

const newObject: { [key: string]: TypeB } = Object.fromEntries(
    Object.entries(oldObject).map(([key, value]) => [
        key,
        {
            d: value.a,
            e: value.b,
            c: value.c
        }
    ])
);

Playground Link

为了详细说明,顾名思义,Object.fromEntriesObject.entries的逆,取[key, value]元素的数组并创建一个对象,将键映射到它们相应的值。

因此,我们像以前一样从Object.entries开始,但是我们没有forEach来填充新对象,而是在数组上map,将每个[key, value]转换为{ {1}}并将结果数组传递到[key, newValue]

请注意,正如jcalz所说,Object.fromEntries是在ES2019中引入的。如果目标运行时不支持ES2019,则需要添加诸如npm:object.fromentries之类的polyfill,并在Object.fromEntries

中相应地指定"lib": ["ES2019"]或更高版本

我删除了类型断言tsconfig.json,因为它既不必要,也将更重要的是抑制诸如as TypeB声明的属性遗忘或拼写错误的错误。类型推断是TypeScript最重要的方面之一。

您对使用TypeBmap的直觉是很自然的。不仅我们在这里使用了reduce,而且在引入map之前,经常使用reduce获得与Object.fromEntries相同的结果。

答案 1 :(得分:0)

您还可以使用lodash的mapValue

const oldObject = {
  x: { a: 1, b: 2, c: 3 },
  y: { a: 11, b: 22, c: 33 },
}

function map(value) {
  return {
    d: value.a,
    e: value.b,
    f: value.c
  };
}

const newObject = mapValues(oldObject, map);

console.log(newObject);