1
votes

The below code is giving me the following type error

No overload matches this call. Overload 1 of 3, '(callbackfn: (previousValue: TestData, currentValue: TestData, currentIndex: number, array: TestData[]) => TestData, initialValue: TestData): TestData', gave the following error. Type 'boolean' is not assignable to type 'TestData'. Overload 2 of 3, '(callbackfn: (previousValue: BooleanObject, currentValue: TestData, currentIndex: number, array: TestData[]) => BooleanObject, initialValue: BooleanObject): BooleanObject', gave the following error. Type 'boolean' is not assignable to type 'BooleanObject'.

is anyone able to help explain why the type is not assignable?

In my mind, in the TestState interface, I defined the property 'booleanObject' to be of type BooleanObject and BooleanObject is an interface which defines a string index property such that when indexed with a string the return value's type should be a boolean.

Then by casting the initial value in the reducer to type BooleanObject,

a) the reducer returns the correct type expected for property 'booleanObject' in the state definition and

b) then when I index the accumulator (of type BooleanObject) I believe I should be expecting the accumulator["index"] value is of type boolean

Where am I lacking to work out why I'm getting a type not assignable error?

Thanks in advance!

import React from 'react';

interface TestProps {
    data: TestData[];
}

interface TestState {
    booleanObject: BooleanObject;
}

interface BooleanObject {
    [index: string]: boolean;
}

interface TestData {
    name: string;
    subData: SubData[];
}

interface SubData {
    name: string;
    value: string;
}

class Test extends React.Component<TestProps, TestState>{
    constructor(props: TestProps){
        super(props);
        this.state = {
            booleanObject: this.props.data.reduce((accumulator, currentValue) => accumulator[currentValue.name] = false, {} as BooleanObject)
        }
    }
}
2

2 Answers

0
votes

Your types look okay.

Basically, in your reduce, when you are returning accumulator[currentValue.name] = false; which means you are returning false(i.e. boolean) and hence the issue.

Just properly return in the reduce callback and your types will be fixed.

Like this

import React from "react";

interface TestProps {
  data: TestData[];
}

interface TestState {
  booleanObject: BooleanObject;
}

interface BooleanObject {
  [index: string]: boolean;
  //   index: boolean;
}

interface TestData {
  name: string;
  subData: SubData[];
}

interface SubData {
  name: string;
  value: string;
}

class Test extends React.Component<TestProps, TestState> {
  constructor(props: TestProps) {
    super(props);
    this.state = {
      booleanObject: this.props.data.reduce((accumulator, currentValue) => {
        accumulator[currentValue.name] = false;
        return accumulator;
      }, {} as BooleanObject),
    };
  }
}

0
votes

The type of reduce function is something like this

Array<T>.reduce(callbackfn: (previousValue: T, currentValue: T, ..) => T): T

meaning, it's result is of the type of elements of the array.

So, since this.props.data is of type TestData[], reduce method must return a result of type TestData which is not the case in your code (which casts and returns BooleanObject).