I have some data which looks like this –
{
System: 'VIT0056',
Value: {
Start: 3.3,
End: 3.9
},
'Initial Range' : {
'Start': '1/12/2022',
'End': '31/12/2022',
},
Manager: 'Karl Woods',
Location: 'Tokyo',
Price: '$1.50',
},
I am currently mapping over this object like so –
{Object.entries(data).map(([key, val]) => {
if (key === 'Value') {
return (
<S.ValueContainer key={key}>
<Label>{key}:</Label>
<Text size="small">** DO SOMETHING HERE TO SHOW VALUES **</Text>
</S.ValueContainer>
)
}
if (key === 'Initial Range') {
return (
<S.ValueContainer key={key}>
<Label>{key}:</Label>
<Text size="small">** DO SOMETHING HERE TO SHOW VALUES ** </Text>
</S.ValueContainer>
)
}
return (
<S.ValueContainer key={key}>
<Label>{key}:</Label>
<Text size="small">{val}</Text>
</S.ValueContainer>
)
}
)
}
For the Value and Initial Range keys I want to be able to show them like this –
Value : 3.3 – 3.9
Initial Range: From 01 Dec 2022 To 31 Dec 2022
However I am having trouble accessing the values due to the fact that they are nested objects.
When I put them inside the if statement and try to do val.Start
it tells me that –
Property ‘Start’ does not exist on type ‘string | Range’.
But I know that the value I’ll be accessing in this block will only be of type Range. Is there a way to define this?
3
Answers
You can use a type assertion to tell your compiler, that the value actually is a
Range
or you can implement a
ToString(value: string | Range)
functionand use this in your rendering
Furthermore, you seem to have different types of ranges also. So when using the
ToString()
approach, you might also need to do a typecheck on your start and end propertiesOf course you can also return some renderings instead of only strings. As in the following example
When you pass your object into
Object.entries
, you are essentially decoupling your keys from the types of their associated values. It looks like the array you are iterating over has type[string, string | Range][]
, presumably withRange
being some custom type defined elsewhere.If you want to access properties on your object in a way where the association between keys and value types is maintained, then you should access them through the object instead of using the
val
argument accessible within your map callback.So instead of
val.Start
, trydata[key].Start
(once you’ve narrowed the type ofkey
of course).This is quite a common issue with union types, the reason the error exists is to stop you from trying to access
Start
when the you have astring
forval
.I would check the type first, like so:
This would then always fall back to just showing the value of
val
and then for the other parts you are free to accessStart
andEnd
on theRange
type.