Retrieve the object's value by utilizing the string index in TypeScript and proceed to access it further


interface IpPatientAddressDto {
  ...
  addressSeq: number;
}

interface IpPatientInfoDto {
  ...
  localAddress: IpPatientAddressDto;
}

const originalPatient:IpPatientInfoDto  = {
  ...
  localAddress:{
     addressSeq:0001
  }
}

 const createAddrCollectionObj = (prop: keyof IpPatientInfoDto) => {
      return {
         addressSeq: originalPatient[prop].addressSeq,  // error:TS2339      
      }
 }

const a1 = createAddrCollectionObj('localAddress'); 

How should I define the prop parameter correctly?

Error in typescript: TS2339: Property 'addressSeq' does not exist on type string | number | Date | IpPatientAddressDto | IpPatientRelationshipDto[]. Property 'addressSeq' does not exist on type string.

I have an idea of how to solve it, but I want to avoid unnecessary complexity.

const get = <T extends keyof ObjType>(key: T): ObjType[T] => {
    return obj[key]
}
let res = get("a"); //"1"

I am thinking that createAddrCollectionObj should be constrained by the type of the prop parameter, and it must have access to other properties such as addressSeq.

When calling createAddrCollectionObj('xxx'), Typescript should be able to verify if xxx matches the corresponding type.

  const createAddrCollectionObj = (prop: keyof IpPatientInfoDto) => {
     const property = originalPatient[prop];
     if (!isIpPatientAddressDto(property,prop)) {
       return null;
     }
     return {
       addressSeq: property.addressSeq,
       patientSeq: property.patientSeq,
       address: patInfo[prop + 'Details'],
       provinceCode: patInfo[prop][0].code,
       provinceName: patInfo[prop][0].name,
       cityCode: patInfo[prop][1].code,
       cityName: patInfo[prop][1].name,
       areaCode: patInfo[prop][2].code,
       areaName: patInfo[prop][2].name,
       zipCode: '', // 邮编
     };
   };

Answer №1

To ensure the type system recognizes the property type, you must implement a key check. Currently, it only identifies that you are passing a key of IpPatientInfoDto, but there are other properties lacking the type IpPatientAddressDto.

const createAddrCollectionObj = (prop: keyof IpPatientInfoDto) => {
    switch (prop)
    {
        case 'localAddress': // originalPatient['localAddress'] is IpPatientAddressDto
            return {
                addressSeq: originalPatient[prop].addressSeq,
            };
        // other cases...
        default:
            return {
                addressSeq: null,
            };
    }
};

Answer №2

Only the localAdress property contains an object with an addressSeq property. TypeScript is assisting you in avoiding the error of trying to access a property that may not exist.

To handle this, you can implement a Type Guard to verify if the object conforms to the expected shape:

function isIpPatientAddressDto(obj: IpPatientInfoDto[keyof IpPatientInfoDto]): obj is IpPatientAddressDto {
  return obj.hasOwnProperty('addressSeq');
}

const createAddrCollectionObj = (prop: keyof IpPatientInfoDto) => {
  const property = originalPatient[prop];
  if (!isIpPatientAddressDto(property)) {
    return {
      addressSeq: defaultValue, //defaultValue should be defined elsewhere   
    };
  }

  return {
    addressSeq: property.addressSeq   
  }
}

const a1 = createAddrCollectionObj('localAddress'); 

This approach allows you to first check for the existence of the property and provide a default value if it does not exist.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Using Javascript to Treat an HTML Document as a String

Check out the complete project on GitHub: https://github.com/sosophia10/TimeCapsule (refer to js/experience.js) I'm utilizing JQuery to develop "applications" for my website. I'm encountering a problem where I can't locate the correct synta ...

Choose elements in the template's DOM

There is a specific template that I consistently reference on the same page: <div ng-controller="templateController"> <div class="source"> <div ng-repeat="item in info"> <div class="content" data-value="{{ite ...

Search MongoDB using regular expressions that disregard any punctuation marks

I'm currently working on querying a MongoDB collection to find a single item based on a string property using react-router-dom's NavLink. The challenge arises when the prop via NavLink contains hyphens instead of spaces, and there are also names ...

How to inject a variable into an AngularJS service that utilizes both $http and $interval functions?

Struggling with $http and $interval, I stumbled upon this code. http://embed.plnkr.co/fSIm8B/script.js I forked it here: http://plnkr.co/edit/Al8veEgvESYA0rhKLn1q To make it more functional, how can I pass a variable to the service? Here is the broken ...

Decoding arrays of JSON data

Receiving "chunked" data (json arrays) on the front-end via "xhr" (onprogress). Handling delayed chunks is easy - just remember response length and offset. The challenge comes when multiple "chunked" responses arrive simultaneously, resulting in an unpars ...

Import csv file into Google Sheets using basic authentication

Looking to retrieve a CSV from a URL that requires basic authentication. I have come across some code that works, but I am having trouble with parsing the CSV, as well as clearing and setting the cells. There are some bugs in the old code that need fixing ...

What is the method for submitting a form when a change occurs?

This inquiry is focused on the Captive Network Assistant. I attempted to utilize plain JavaScript, <form action=""> <select name="test" onchange="this.form.submit()"> <option value="1">1</option> <option val ...

What is the best way to utilize {...this.props} within a functional component?

I recently purchased a React-Native course on Udemy where the instructor used {...this.props} but unfortunately, it caused an error for me. The error message I received was: TypeError: undefined is not an object(evaluating '_this.props') Any ...

The page unexpectedly stalls without any explanation

Lately, I've been exploring the capabilities of MyJSON. I attempted to create a function to retrieve data from my database in order to avoid manually typing lengthy text each time I needed it. However, whenever I ran the code, my page would freeze wit ...

Sending an AJAX variable to JavaScript

Help me understand how I can pass an ajax variable to javascript in the following code example. Please note that while the 'append' function works, it may not be the most efficient solution. $.ajax({ type: "POST", dataT ...

Having trouble with cc email addresses causing problems in Outlook

I'm encountering an issue where there is a '&' symbol in one of the cc email addresses. Due to the default behavior of the browser, the complete email address is not being displayed properly in Outlook. Here's an example: let to='a ...

Issue with updating onclick attribute of popover in Bootstrap 4

My goal is to design a popover in bootstrap 4 with a nested button inside it. However, when I update the data-content attribute of the popover with the button element, the element gets updated but the onclick attribute goes missing. I have experimented wi ...

Tips for fetching paginated HTTP requests from a backend API using Observables within Angular 4

My Angular 4 app has a service that retrieves a variable number of pages from a back-end API. I came across a solution on Stack Overflow which suggests using flatMap, but it doesn't work for me as the number and URLs of requests are dynamic and unkno ...

Ways to launch the React Material date picker while hiding the date input field

I am working with the react material (MUI-X) date picker and my specific requirement is to have the date picker open on button click without displaying the date text field. I simply want to show the calendar and allow users to select a date. I have explore ...

javascript Why isn't the initial click registering?

In my table, users can select certain rows by using checkboxes. I have implemented some JavaScript functionality that allows them to select each checkbox individually and also use a "Select All" option. Additionally, there is code written to enable the use ...

Can one mimic a TypeScript decorator?

Assuming I have a method decorator like this: class Service { @LogCall() doSomething() { return 1 + 1; } } Is there a way to simulate mocking the @LogCall decorator in unit tests, either by preventing it from being applied or by a ...

Is there a way for me to come back after all child http requests have finished within a parent http request?

I am currently utilizing an API that provides detailed information on kills in a game. The initial endpoint returns an ID for the kill event, followed by a second endpoint to retrieve the names of both the killer and the killed player. Due to the structur ...

using an array as an argument in the filtering function

Is there a way to pass an array to the filter method in JavaScript? I have successfully filtered an array using another array. However, my filter array currently has a global scope. How can I pass the array to make my code cleaner? var array = [1, 2, 3, ...

injecting javascript dynamically using jquery

I am attempting to conditionally load a script in the case that the browser being used is IE8. To achieve this, I have employed jQuery's .getScript function as it allows me to execute certain actions after the script has been loaded. The issue lies in ...

Is the reordering of items in an Angular JS array causing a malfunction with the first item

It appears that there may be a syntax error present in my code. Within my controller, I have a set of 4 functions: adding a new item, deleting the current item, moving an item backward (up) in the array, and moving an item forward (down) in the array. Al ...