Typescript 中的 reduce() 函数实例化空对象

Ben*_*inK 4 javascript typescript

我正在尝试将我的 Javascript 函数转换为它的 Typescript 版本,但我无法摆脱读取的带下划线的代码acc[curr.name](在 VSCode 中)。将鼠标悬停在其上时会显示:

元素隐式具有“any”类型,因为“string”类型的表达式不能用于索引类型“{}”。在类型“{}”上找不到带有“string”类型参数的索引签名。

我正在按键名称计算出现次数。

我应该在哪里定义类型以及为什么空对象或带有数字的对象不起作用。我不确定如何解决它,因为我尝试了多种方法,例如:

data.reduce<{}>()data.reduce<{property: number}>()

代码:

const data = [
  { name: "name1", },
  { name: "name1", },
  { name: "name1", },
  { name: "name1", },
  { name: "name2", },
  { name: "name2", },
  { name: "name2", },
  { name: "name1", },
];

// count data by key name
const resultData = data.reduce((acc, curr) => {
  return acc[curr.name] ? ++acc[curr.name] : (acc[curr.name] = 1), acc;
}, {});
Run Code Online (Sandbox Code Playgroud)

运行时结果:

const resultData = {
  name1: 4,
  name2: 3,
  name3: 1,
};
Run Code Online (Sandbox Code Playgroud)

zma*_*mag 10

设置索引签名,例如data.reduce<{ [index: string]: number }>

参考: https: //www.typescriptlang.org/docs/handbook/2/objects.html#index-signatures

const resultData = data.reduce<{ [index: string]: number }>((acc, curr) => {
  return acc[curr.name] ? ++acc[curr.name] : (acc[curr.name] = 1), acc;
}, {});
Run Code Online (Sandbox Code Playgroud)

或者您可以使用as带有初始值的关键字。

const resultData = data.reduce((acc, curr) => {
  return acc[curr.name] ? ++acc[curr.name] : (acc[curr.name] = 1), acc;
}, {} as { [index: string]: number });
Run Code Online (Sandbox Code Playgroud)