0

I am trying to refactor some react-typescript code and I want to make one general component, and call it with different parameters several times, instead of having several components that work in the same way.

So I am using redux as well, and the way it works is that in each component I call the redux state, and now I want to do it differently. I have made a component that is called DrawerItems and in there I have defined :

type DrawerItemProps = {
    open: boolean,
    tabs: boolean[],
  }

const DrawerItems = ({ open, tabs }: DrawerItemProps) => {
.
.
.
}

in my parent component I have

  const jaTabs = useSelector((state: TabState) => state.JA.tabs);
  const checkedOpen = useSelector((state: TabState) => state.JA.open);

and then I want to pass the to my child component like:

<DrawerItems open={checkedOpen } tabs={jaTabs } />

this generates the error:

Type '{ trunk: boolean; hip: boolean; knee: boolean; ankle: boolean; }' is missing the following properties from type 'boolean[]': length, pop, push, concat, and 29 more.

My state looks like this:

export interface TabState {
    ja: {
        open : boolean;
        tabs : {
            trunk: boolean;
            hip: boolean;
            knee: boolean;
            ankle: boolean;
        }
    }
    //=================
    fp: {
        open : boolean;
        tabs : {
            clearanceSwing: boolean;
            footOrientation: boolean;
        }
    }
    //=================
    gt: {
        open : boolean;
        tabs : {
            gaitWidth: boolean;
            centerOfMass: boolean;
            eCenterOfMass: boolean;
        }
    }
    //=================
    tm: {
        open : boolean;
        tabs : {
            gaitSpeed: boolean;
            stancePhaseDuration: boolean;
            swingPhaseDuration: boolean;
                }
    }
    //=================
    distance: {
        open : boolean;
        tabs : {
            stepLength: boolean;
            strideLength: boolean;
            distanceWalked: boolean;
        }
    }
}

how can I correctly pass the boolean array down to my child component? I want to be able to pass the tabs everytime to my DrawerItem how can I do that?

1
  • 2
    you defined your tabs type as an array of booleans but in your TabState interface, you have an object that contains boolean values. I believe this mismatch is what's raising an error. Commented Apr 18, 2022 at 13:48

4 Answers 4

1

You are getting the error because you are giving to tabs a different type to what really is. Here,

tabs: boolean[]

You are saying that tabs is an array of boolean. However here:

tabs : {
 trunk: boolean;
 hip: boolean;
 knee: boolean;
 ankle: boolean;
}

You are saying that tabs is an object with those keys. So what you can do is creating an interface that you can import in your DrawerItems component:

export interface ITabs{
 trunk: boolean;
 hip: boolean;
 knee: boolean;
 ankle: boolean;
}
tabs: ITabs;
Sign up to request clarification or add additional context in comments.

Comments

1

In your type declaration you declare tabs as a boolean array

type DrawerItemProps = {
    open: boolean,
    tabs: boolean[],
  }

But in your interface you declare the tabs as an object

export interface TabState {
    ja: {
        open : boolean;
        /// Here v
        tabs : {
            trunk: boolean;
            hip: boolean;
            knee: boolean;
            ankle: boolean;
        }
    }
// ...

The type error basically tells you that you pass the the wrong prototype (object instead of array) that's why the error states properties are missing.

I don't know what your further implementation is, so depending on that you could choose to use either objects or arrays.

Comments

1

I would do the refactor in this way. Also you try to assign type of object in array type

export interface Tabs {
   trunk: boolean;
   hip: boolean;
   knee: boolean;
   ankle: boolean;
 }
    

export interface TabState {
    ja: {
        open : boolean;
        tabs : Tabs
    }
    //=================
    fp: {
        open : boolean;
        tabs : {
            clearanceSwing: boolean;
            footOrientation: boolean;
        }
    }
    //=================
    gt: {
        open : boolean;
        tabs : {
            gaitWidth: boolean;
            centerOfMass: boolean;
            eCenterOfMass: boolean;
        }
    }
    //=================
    tm: {
        open : boolean;
        tabs : {
            gaitSpeed: boolean;
            stancePhaseDuration: boolean;
            swingPhaseDuration: boolean;
                }
    }
    //=================
    distance: {
        open : boolean;
        tabs : {
            stepLength: boolean;
            strideLength: boolean;
            distanceWalked: boolean;
        }
    }
}

And in react component pass type in this way

type DrawerItemProps = {
    open: boolean,
    tabs: Tabs,
  }

const DrawerItems = ({ open, tabs }: DrawerItemProps) => {
.
.
.
}

Comments

1

It's happening because u are passing to DrawerItems tab param an object with the type of "TabState ja prop", but define type of tab as boolean[].

You can solve this problem using generics

type DrawerItemProps<T> = {
    open: boolean,
    tabs: T,
}

function DrawerItems<T>({ open, tabs }: DrawerItemProp) {
.
.
.
}

Or using pipe with Lookup Types to extract nested types in TabState, something like this:

type DrawerItemProps = {
    open: boolean,
    tabs: TabState['ja']['tabs'] |  TabState['fp']['tabs'] | TabState['gt']['tabs'] ...etc
}

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.