我有一个像这样的对象数组
type AnyType = {
name: 'A' | 'B' | 'C';
isAny:boolean;
};
const myArray :AnyType[] =[
{name:'A',isAny:true},
{name:'B',isAny:false},
]
我想在myArray
和reduce
上运行以获得仅名称的数组
const namesArray=myArray.reduce<AnyType['name'][]>((a,b)=>{
return b.name;
},[])
但是我得到一个typeScript错误
(parameter) b: AnyType
BugFinder: No overload matches this call.BugFinder:
Overload 1 of 6, '(callbackfn: (previousValue: ("A" | "B" | "C")[], currentValue: AnyType, currentIndex: number, array: AnyType[]) => ("A" | "B" | "C")[], initialValue: ("A" | "B" | "C")[]): ("A" | ... 1 more ... | "C")[]', gave the following error.BugFinder:
Argument of type '(a: ("A" | "B" | "C")[], b: AnyType) => "A" | "B" | "C"' is not assignable to parameter of type '(previousValue: ("A" | "B" | "C")[], currentValue: AnyType, currentIndex: number, array: AnyType[]) => ("A" | "B" | "C")[]'.BugFinder:
Type '"A" | "B" | "C"' is not assignable to type '("A" | "B" | "C")[]'.BugFinder:
Type '"A"' is not assignable to type '("A" | "B" | "C")[]'.BugFinder:
Overload 2 of 6, '(callbackfn: (previousValue: ("A" | "B" | "C")[], currentValue: AnyType, currentIndex: number, array: AnyType[]) => ("A" | "B" | "C")[], initialValue: ("A" | "B" | "C")[]): ("A" | ... 1 more ... | "C")[]', gave the following error.BugFinder:
Argument of type '(a: ("A" | "B" | "C")[], b: AnyType) => "A" | "B" | "C"' is not assignable to parameter of type '(previousValue: ("A" | "B" | "C")[], currentValue: AnyType, currentIndex: number, array: AnyType[]) => ("A" | "B" | "C")[]'.BugFinder:
Type '"A" | "B" | "C"' is not assignable to type '("A" | "B" | "C")[]'.BugFinder:
Type '"A"' is not assignable to type '("A" | "B" | "C")[]'.
游乐场
返回值为数组:
const NamesArray = myArray.reduce<AnyType["name"][]>(
(a, { name }) => [...a, name],
[]
);
使用Array#map
的另一种方法:
const NamesArray = myArray.map<AnyType["name"]>(({ name }) => name);
如果你只是想将数组'映射'到另一个数组,你应该使用myArray。但是如果你想具体使用reduce,比如说在过程中也要过滤,那么问题就出在reducer回调上。
reducer应该返回累加器
这是TS给您的错误,您返回的是(当前元素的)名称,而不是名称数组。
这是一个reduce同时映射和过滤的例子:
const namesArray = myArray.reduce<AnyType['name'][]>( ( accumulatorArr, currentValue ) => {
if ( currentValue.isAny ) {
accumulatorArr.push( currentValue.name );
}
return accumulatorArr;
}, [] );
如果您想使用Array.reduce()来做,那么这将是有用的。但是正如@majed Badawi所提到的,我们可以使用Array.map()轻松地做到这一点。
interface AnyType {
name: 'A' | 'B' | 'C';
isAny: boolean;
}
const myArray: AnyType[] = [
{ name: 'A', isAny: true },
{ name: 'B', isAny: false },
];
const namesArray = myArray.reduce((a, b) => {
a.push(b.name);
return a;
}, [] as string[]);
注意:我也对你的类型声明做了一些改变。这是我喜欢的使用方式。如果你愿意,请把它改成你的表格!
试试这个:
const NamesArray=myArray.reduce<AnyType['name']|[]>((a:AnyType['name']|[],b:AnyType)=>{
return b.name;
},[])