I am using the nested object and trying to get to the properties using Object.keys() and forEach(). The problem is when I want to get to the nested keys filteringState[item][el].
How to type function like this?
interface InitialStateTypes {
country: {
"italy": boolean,
},
board: {
"full": boolean,
},
transport: {
"bus": boolean,
"own": boolean
},
}
interface FilteringDataTypes {
country: string[],
board: string[],
transport: string[],
}
const collectFilteringData = (filteringState: InitialStateTypes) => {
let filteringData = <FilteringDataTypes>{};
Object.keys(filteringState).forEach((item) => {
Object.keys(filteringState[item]).forEach((el) => {
if (filteringState[item][el]) {
if (!filteringData[item]) {
filteringData[item] = [el];
} else {
filteringData[item] = [...filteringData[item], el];
}
}
});
});
return filteringData;
};
export default collectFilteringData;
It can get a little messy when using the keys
method, because it only expects to output strings. (It is not unreasonable since JS Object keys are considered strings, of course TypeScript worries about this more)
Below is a possible way it could be done:
interface InitialStateTypes {
country: {
"italy": boolean,
},
board: {
"full": boolean,
},
transport: {
"bus": boolean,
"own": boolean
},
}
interface FilteringDataTypes {
country: string[],
board: string[],
transport: string[],
}
const collectFilteringData = (filteringState: InitialStateTypes):FilteringDataTypes => {
let filteringData = {} as FilteringDataTypes
(Object.keys(filteringState) as Array<keyof InitialStateTypes>).forEach((item) => {
(Object.keys(filteringState[item]) as Array<keyof InitialStateTypes[typeof item]>).forEach((el) => {
if (filteringState[item][el]) {
if (!filteringData[item]) {
filteringData[item] = [el];
} else {
filteringData[item] = [...filteringData[item], el];
}
}
});
});
return filteringData;
};
export default collectFilteringData
forEach
methodtypeof item
from the first forEach
Formatted (with Prettier), it ends up looking like this:
const collectFilteringData = (
filteringState: InitialStateTypes
): FilteringDataTypes => {
let filteringData = {} as FilteringDataTypes;
(Object.keys(filteringState) as Array<keyof InitialStateTypes>).forEach(
(item) => {
(
Object.keys(filteringState[item]) as Array<
keyof InitialStateTypes[typeof item]
>
).forEach((el) => {
if (filteringState[item][el]) {
if (!filteringData[item]) {
filteringData[item] = [el];
} else {
filteringData[item] = [...filteringData[item], el];
}
}
});
}
);
return filteringData;
};
I've written this answer as of TypeScript 4.6.2, the keys
method is typed like so:
keys(o: object): string[];