如何输入此 reduce 回调?

How do I type this reduce callback?

我正在尝试使用 reduce 创建简单的 CSV 样式 header。

我有一个 objects 数组,每个数组都有一个 'title' 参数,我想将它们缩减为一个带逗号的字符串。

这是我的函数:

     const colHeader: string = props.columns.reduce((curr: CustomColumn<T>, prev: CustomColumn<T>, index: number):string => {
 return index === 0 ? curr.title : prev.title + ","                                                                                                                  
  }, "")

我从 typescript 编译器得到的错误是 string 和 CustomColumn 没有共同的属性。如果有人能解释如何正确输入,那就太好了...

谢谢

第一个参数的类型不应该是CustomColumn<T>,应该是string。这是累加器的类型,基于您为其提供的初始化值 ("") 以及您在回调中返回的内容。

你的回调也有错误,curr.title应该就是curr:

return index === 0 ? curr : prev.title + ","                                                                                                                  
//                       ^−−−−− no `.title.`

所以:

const colHeader: string = props.columns.reduce((curr: string, prev: CustomColumn<T>, index: number): string => {
    return index === 0 ? curr : prev.title + ","
}, "");

Playground link

话虽如此,您很少需要显式键入参数以像那样内联回调。 TypeScript 非常擅长推断它们:

const colHeader = props.columns.reduce((curr, prev, index) => {
    return index === 0 ? curr : prev.title + ","                                                                                                                  
}, "");

Playground link


不过,回过头来看,这段代码跳过了第一列的标题。通常,reduce 几乎从来都不是可以使用的工具(除非您正在执行 FP 并将预定义函数传递给 reduce)。

如果您只想要 所有 个标题,则作为 Grégory NEUT says,使用 mapjoin:

const colHeader = props.columns.map(({title}) => title).join(",");

同样,TypeScript 会很好地推断类型。

如果你故意跳过第一个,你可以使用 slice:

const colHeader = props.columns.slice(1).map(({title}) => title).join(",");

首先你混淆了prevcurr,而且prev是一个string

interface CustomColumn<T> {
  title: string;
}

type T = string;

const colHeader: string = [{
  title: 'columnA',
}, {
  title: 'columnB',
}].reduce((prev: string, curr: CustomColumn<T>, index: number): string => index === 0 ? curr.title : prev + ", " + curr.title, "");

console.log(colHeader);

playground


此外,下面的更简单(映射仅提取标题,然后连接以从标题创建字符串)

const colHeaderB: string = [{
  title: 'columnA',
}, {
  title: 'columnB',
}].map((x:CustomColumn<T>):string => x.title).join(', ');