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?
CodePudding user response:
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;
CodePudding user response:
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.
CodePudding user response:
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) => {
.
.
.
}
CodePudding user response:
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
}