Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Accessing values with different types in object map

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 –

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

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?

>Solution :

You can use a type assertion to tell your compiler, that the value actually is a Range

<Text size="small">{(val as Range).Start} - {(val as Range).End}</Text>

or you can implement a ToString(value: string | Range) function

function ToString(value: string | Range) {
  //if value is a string, just return the value
  if (typeof value === "string") return value;

  //here the compiler knows it must be a Range
  //because it's not a string ...
  return `${value.Start} - ${value.End}`;
}

and use this in your rendering

<Text size="small">{ToString(val)}</Text>

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 properties

function ToString(value: string | Range) {
  if (typeof value === "string") return value;

  if (typeof value.Start === "number")
    return `${value.Start} - ${value.End}`;

 //here you know value is a range and
 //the properties of range are strings
 //(given both always have the same type

  //or apply appropriate formatting for your dates
  return `${value.Start} to ${value.End}`;

}

Of course you can also return some renderings instead of only strings. As in the following example

function ToRender(value: string | Range) {
  //if value is a string, just return the value
  if (typeof value === "string") return (<div>{value}</div>);

  //here the compiler knows it must be a Range
  //because it's not a string ...
  return (<div><span>{value.Start}</span> to <span>{value.End}</span></div>)
}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading