likes
comments
collection
share

Array.reduce 的类型你会写吗?

作者站长头像
站长
· 阅读数 7

使用 reduce 的时候我们通常会遇到 TS 类型报错:

const array = [
  { key: "name", value: "Daniel" },
  { key: "age", value: "26" },
  { key: "location", value: "UK" },
];

const grouped = array.reduce((obj, item) => {
  obj[item.key] = item.value;
  return obj;
}, {});

第 8 行会报错:

Array.reduce 的类型你会写吗?

Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{}'.  
No index signature with a parameter of type 'string' was found on type '{}'.(7053)

你可以复制代码到 ts playground 试试能否解决。

为什么会报错

因为 obj 的类型是从 reduce 的第二个参数 {} 推导的,而 {} 类型等价于 Record<never, never>,即不能有任何 key 的对象,故不能对其增加 key obj[item.key] = item.value; ❌。解决思路是显示告诉其类型。

办法 1:用 as 强制断言

const grouped = array.reduce((obj, item) => {
  obj[item.key] = item.value;
  return obj;
}, {} as Record<string, string>); // <-

办法 2:给参数加类型

const grouped = array.reduce(
  (obj: Record<string, string>, item) => { // <-
    obj[item.key] = item.value;
    return obj;
  },
  {}
);

办法 3:给 reduce 增加泛型

const grouped = array.reduce<Record<string, string>>( // <-
  (obj, item) => {
    obj[item.key] = item.value;
    return obj;
  },
  {}
);

为什么能想到这种办法,其实我们通过查看 array.reduce 的 TS 类型源码可以得知其可以接受泛型。


翻译自 How To Type Array.reduce 作者是著名的 TS 解密大师 Matt Pocock。

文章结束祝大家都能拿到心仪的 offer 🎉!