How to check if type is array?

I have the following interface
interface IFilterOptions {
price: {
min: number,
max: number,
},
item_type: string[],
state: string[],

[key: string]: string[] | {min: number, max: number};
}
interface IFilterOptions {
price: {
min: number,
max: number,
},
item_type: string[],
state: string[],

[key: string]: string[] | {min: number, max: number};
}
How can I check if i'm dealing with the object type or the string[] type while mapping through the key's of IFilterOptions ie:
Object.keys(filterOptions).forEach((filter) => {
if (filter === "price") {
....
return;
} else if (Array.isArray(filterOptions[filter]) && !filterOptions[filter].includes("test"))
❌❌ -> Property 'includes' does not exist on type 'string[] | { min: number; max: number; }' ❌❌
}
});
Object.keys(filterOptions).forEach((filter) => {
if (filter === "price") {
....
return;
} else if (Array.isArray(filterOptions[filter]) && !filterOptions[filter].includes("test"))
❌❌ -> Property 'includes' does not exist on type 'string[] | { min: number; max: number; }' ❌❌
}
});
9 Replies
Unknown User
Unknown User2y ago
Message Not Public
Sign In & Join Server To View
Sean Cassiere
Sean Cassiere2y ago
This would also work.
[...Object.entries(filterOptions)].forEach(([key, value]) => {
if (key === "price") {
// whatever custom logic you have here
return;
}

if (Array.isArray(value) && !value.includes("test")) {
// whatever logic goes here
}
});
[...Object.entries(filterOptions)].forEach(([key, value]) => {
if (key === "price") {
// whatever custom logic you have here
return;
}

if (Array.isArray(value) && !value.includes("test")) {
// whatever logic goes here
}
});
Xaohs
Xaohs2y ago
Exactly what I needed. Could you explain why this does work as opposed to what I had first though? Also thanks for this, gonna read through it when I have some time
Sean Cassiere
Sean Cassiere2y ago
Cannot say for certain TBH. What I do know is that in my version of it, I'm directly passing the value into the Array.isArray vs accessing the reference of it on the object outside of the context of the .forEach.
Xaohs
Xaohs2y ago
Yea that could be the reason. Thanks!! Trying to implement it with type predicates, as it seems like the cleaner solution, but having some trouble. I made the following guard:
function isObject(item: string[] | { min: number; max: number }): item is { min: number; max: number } {
return (item as { min: number; max: number }).min !== undefined && (item as { min: number; max: number }).max !== undefined;
}
function isObject(item: string[] | { min: number; max: number }): item is { min: number; max: number } {
return (item as { min: number; max: number }).min !== undefined && (item as { min: number; max: number }).max !== undefined;
}
Which should guarantee that it is specifically of type {min: number; max:number} yet
Object.keys(filterOptions).forEach((filter) => {
if (isObject(filterOptions[filter])) {
filterOptions[filter].min;
❌❌ Property 'min' does not exist on type 'string[] | { min: number; max: number; }' ❌❌
}
});
Object.keys(filterOptions).forEach((filter) => {
if (isObject(filterOptions[filter])) {
filterOptions[filter].min;
❌❌ Property 'min' does not exist on type 'string[] | { min: number; max: number; }' ❌❌
}
});
I think the Object.keys().forEach() is messing with the outcome of this
Unknown User
Unknown User2y ago
Message Not Public
Sign In & Join Server To View
Xaohs
Xaohs2y ago
Yeah. Handling them individually without Object.keys works. Guess it's not much of a problem. Wanted to make it more generic in case I added more filters later on, but not too big a deal. Learnt something new, type predicates. Thanks 😉
Unknown User
Unknown User2y ago
Message Not Public
Sign In & Join Server To View
Xaohs
Xaohs2y ago
Oh that makes so much sense, what an oversight haha. I'll try it out tomorrow, thanks a lot
Want results from more Discord servers?
Add your server