Reputation: 2294
I want to map over an array that has two different types, an make the map render data depending on the condition at hand.
const component = () => {
const [arr, setArr] = useState<{ arr: ({} | {id : string)[] | null }>({ arr: null });
useEffect(() => {
setArr([{id : 1},{id : 2 },{},{},{}])
},[]}
return (
<div style={{ display: "flex", flexDirection: "column" }}>
{arr?.map((el, i) =>
id in el ? (
<div key={i}>{el.id}</div>
) : (
<div>
{'ids to fill'}
</div>
)
)}
</div>
)}
Upvotes: 1
Views: 138
Reputation: 1585
You need to use typescritp type predicates. These are functions that ensure the typescript compiler that a variable is of a certain type.
Modified working sandbox link working sandbox link
Changes to your example:
type TypeWithID = {
id: string;
};
//type predicate function
const isOfTypeTypeWithID = (item: any): item is TypeWithID => {
//probably more strict check
return item.id !== undefined;
};
const [arr, setArr] = useState<{ arr: ({} | TypeWithID)[] | null }>({
arr: null
});
/// rendering - now when we call the isOfTypeTypeWithID(el) , this ensures that in the "then" the element is indeed of the correct type
return (
<div style={{ display: "flex", flexDirection: "column" }}>
{arr.arr?.map((el, i) =>
isOfTypeTypeWithID(el) ? (
<div key={i}>{el.id}</div>
) : (
<div>{"ids to fill"}</div>
)
)}
</div>
);
Upvotes: 1