1

I have an array of objects like this

type AnyType = {
  name: 'A' | 'B' | 'C';
  isAny:boolean;
};

const myArray :AnyType[] =[
  {name:'A',isAny:true},
  {name:'B',isAny:false},
]

I want to run on myArray with reduce to get array for name only

const namesArray=myArray.reduce<AnyType['name'][]>((a,b)=>{
  return b.name;
},[])

but I get a typeScript error

(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")[]'.

playground

4 Answers 4

2

The return value is an array:

const NamesArray = myArray.reduce<AnyType["name"][]>(
  (a, { name }) => [...a, name],
  []
);

Another way using Array#map:

const NamesArray = myArray.map<AnyType["name"]>(({ name }) => name);
Sign up to request clarification or add additional context in comments.

2 Comments

my question is about to reduce
answer updated.
1

If you just wanna 'map' the array to a different array, you should use the myArray.map method;
But if you want to specifically use reduce, let's say to also filter in the process, then the problem is with the reducer callback.
The reducer should return the accumulator, which in your case is an array of names;
This is the error TS is giving you, you're returning a name (of the current element) instead of an array of names.

This is an example of a reduce which maps and filters at the same time:

const namesArray = myArray.reduce<AnyType['name'][]>( ( accumulatorArr, currentValue ) => {
  if ( currentValue.isAny ) {
    accumulatorArr.push( currentValue.name );
  }
  return accumulatorArr;
}, [] );

Comments

0

If you want to do it using Array.reduce(), then this will be useful. But as @majed Badawi mentioned, we can do it using Array.map() easily.

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[]);

NOTE: I did some changes to your type declaration as well. This is the way that I preferred to use it. Please change it to your form if you prefer that way!

Comments

0

Try this:

const NamesArray=myArray.reduce<AnyType['name']|[]>((a:AnyType['name']|[],b:AnyType)=>{ 
  return b.name;
},[])

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.