React Js json response to Typescript object

Last updated : January 9, 2023

React Js uses API calls to retrieve data for its components. The API calls usually return JSON data. If I use Typescript in my React Js application, I must cast the JSON response to a compatible Typescript interface to access the JSON response data. Let's see how to achieve that.

JSON response object

I will use the below JSON response to design my interface. It covers most of the scenarios we encounter in JSON responses.

{
  "contactDetails": {
    "firstName": "Micky",
    "lastName": "Mouse",
    "email": "mm@disneyland.com",
    "address": {
      "street": "Some street",
      "city": "Anaheim",
      "state": "CA",
      "zip": "9280"
    },
    "phone": [{
      "number": "1800-Disney",
      "type": "home"
    },
    {
      "number": "1800-Disney",
      "type": "cell"
    }
    ]
  },
  "workDetails": {
    "companyName": "LearnBestCoding",
    "address": {
      "street": "Some street",
      "city": "Edmond",
      "state": "OK",
      "zip": "73034"
    },
    "phone": {
      "number": "1800-work",
      "type": "direct"
    }
  },
  "experience": {
    "releventExperience": "10 years",
    "company": [{
      "name": "Company 1",
      "position": "Research Scientist",
      "fromTo": "2022 - Present"
    }, {
      "name": "Company 2",
      "position": "Research Assistant",
      "fromTo": "2012 - 2021"
    }, {
      "name": "Company 3",
      "position": "Architect",
      "fromTo": "2011 - 2012"
    }]
  },
  "education": {
    "institutions": [{
      "name": "UCO",
      "certification": "BSc Computer Science"
    }, {
      "name": "UCLA",
      "certification": "MSc Computer Science"
    }]
  }
}

Design interface to match JSON response

I can break down my JSON response into four main objects.

{
  contactDetails: {},
  workDetails: {},
  experience: {},
  education: {}
}

Now let's take a look at the contactDetails object. It has an address object and an array of phone numbers.

contactDetails: {
   address: {},
   phone: []
}

Now I have built a skeleton for the contactDetails object. Let's fill in the rest of the properties to complete the contactDetails.

contactDetails: {
    firstName: string
    lastName: string
    email: string
    address: {
      street: string
      city: string
      state: string
      zip: string
    },
    phone: {
      type: string
      number: string
    }[]
}

The workDetails object also contains the address and phone objects.

workDetails: {
    companyName: string
    address: {
      street: string
      city: string
      state: string
      zip: string
    },
    phone: {
      type: string
      number: string
    }
}

The experience and education objects can be composed like the below.

experience: {
    releventExperience: string
    company: {
      name: string
      position: string
      fromTo: string
    }[]
}
education: {
    institutions: {
      name: string
      certification: string
    }[]
}

The address and phone objects are common for contactDetails and workDetails objects. Therefore, bringing those two into two separate interfaces is a good practice.

interface Address {
  street: string
  city: string
  state: string
  zip: string
}

interface Phone {
  type: string
  number: string
}

With that change, my contactDetails and workDetails objects look like the below.

contactDetails: {
    firstName: string
    lastName: string
    email: string
    address: Address,
    phone: Phone[]
  }
  workDetails: {
    companyName: string
    address: Address,
    phone: Phone
}

Next, I must pick a meaningful name for the entire object. The interface name Candidate sounds like a good candidate. Here is the complete code example of what I have explained here. For the sake of simplicity, I don't call an API. Instead, I use a hard-coded JSON. So I can contain the entire example into a single file.

import styles from './Table.module.css'

const json = {
  "contactDetails": {
    "firstName": "Micky",
    "lastName": "Mouse",
    "email": "mm@disneyland.com",
    "address": {
      "street": "Some street",
      "city": "Anaheim",
      "state": "CA",
      "zip": "9280"
    },
    "phone": [{
      "number": "1800-Disney",
      "type": "home"
    },
    {
      "number": "1800-Disney",
      "type": "cell"
    }
    ]
  },
  "workDetails": {
    "companyName": "LearnBestCoding",
    "address": {
      "street": "Some street",
      "city": "Edmond",
      "state": "OK",
      "zip": "73034"
    },
    "phone": {
      "number": "1800-work",
      "type": "direct"
    }
  },
  "experience": {
    "releventExperience": "10 years",
    "company": [{
      "name": "Company 1",
      "position": "Research Scientist",
      "fromTo": "2022 - Present"
    }, {
      "name": "Company 2",
      "position": "Research Assistant",
      "fromTo": "2012 - 2021"
    }, {
      "name": "Company 3",
      "position": "Architect",
      "fromTo": "2011 - 2012"
    }]
  },
  "education": {
    "institutions": [{
      "name": "UCO",
      "certification": "BSc Computer Science"
    }, {
      "name": "UCLA",
      "certification": "MSc Computer Science"
    }]
  }
}

interface Address {
  street: string
  city: string
  state: string
  zip: string
}

interface Phone {
  type: string
  number: string
}

interface Candidate {
  contactDetails: {
    firstName: string
    lastName: string
    email: string
    address: Address,
    phone: Phone[]
  }
  workDetails: {
    companyName: string
    address: Address,
    phone: Phone
  }
  experience: {
    releventExperience: string
    company: {
      name: string
      position: string
      fromTo: string
    }[]
  }
  education: {
    institutions: {
      name: string
      certification: string
    }[]
  }
}

const response: Candidate = json

const App = () => {
  return <table className={styles.customers}>
    <tr><td>First Name</td><td>{response.contactDetails.firstName}</td></tr>
    <tr><td>Last Name</td><td>{response.contactDetails.lastName}</td></tr>
    <tr><td>Email</td><td>{response.contactDetails.email}</td></tr>
    <tr>
      <td>Address</td>
      <td>
        {response.contactDetails.address.street}<br/>
        {response.contactDetails.address.city}<br/>
        {response.contactDetails.address.state}<br/>
        {response.contactDetails.address.zip}
      </td>
    </tr>
    <tr>
      <td>Phone</td>
      <td>{response.contactDetails.phone.map((phone) => {
        return <>{`${phone.type} ${phone.number}`}<br/></>
      })}</td>
    </tr>
    <tr><td>Company</td><td>{response.workDetails.companyName}</td></tr>
    <tr>
      <td>Address</td>
      <td>
        {response.workDetails.address.street}<br/>
        {response.workDetails.address.city}<br/>
        {response.workDetails.address.state}<br/>
        {response.workDetails.address.zip}
      </td>
    </tr>
    <tr>
      <td>Phone</td>
      <td>{`${response.workDetails.phone.type} ${response.workDetails.phone.number}`}</td>
    </tr>
    <tr><td>Experience</td><td>{response.experience.releventExperience}</td></tr>
    <tr>
      <td>Companies</td>
      <td>{response.experience.company.map((exp) => {
        return <>{`${exp.name} ${exp.position} ${exp.fromTo}`}<br/></>
      })}</td>
    </tr>
    <tr>
      <td>Education</td>
      <td>{response.education.institutions.map((institute) => {
        return <>{`${institute.name} ${institute.certification}`}<br/></>
      })}</td>
    </tr>
  </table>
}
export default App;
L Raney
By: L Raney
Lance is a software engineer with over 15 years of experience in full-stack software development.
Read more...

Comments are disabled

No Comments