Asserting within a specific condition's scope in TypeScript

I am facing a similar situation,

type Field1Type = {
   a: string;
}

type Field2Type = {
   b: string;
   c: number;
}

type ObjType = {
   field: Field1Type | Field2Type
}

const field = {
   b: ""
   c: 0
}

const obj = { field } as ObjType

if (some_condition) {
   // TypeScript gives an error: Property 'b' does not exist on type 'Field1Type'.ts(2339)
   console.log(obj.field.b)
}

My scenario involves having an object with a field that can have different types.

When trying to access the field properties, I receive the TypeScript warning because it cannot determine if the field is of type Field1Type or Field2Type.

This issue can be addressed by:

if (some_condition) {
   const temp = obj.field as Field2Type

   // TypeScript errors: Property 'b' does not exist on type 'Field1Type'.ts(2339)
   console.log(temp.b)
}

However, this solution may not seem very elegant.

My question is, is there a more graceful way to assert the field within the condition?

Answer №1

The structure and design of your data organization are unspecified, but it appears to be incorrect to assign two completely different types to the same "field." It would be more organized to create separate properties for clarity. For example:

  type ObjType = {
   field1: Field1Type;
   field2: Field2Type;
   }

If combining the types into one field is necessary, then what you have done is generally correct. Another approach could be:

obj.field = <Field2Type>(obj.field);

If in your use-case the types are not mutually exclusive, meaning they are extensions rather than distinct types, you can merge them like this -

type Field2Type = Field1Type & {
  b: string;
  c: number;
};

Then, by default, the field in obj will be Field2Type.

type ObjType = {
   field: Field2Type
}

This way, there is no need for explicit mapping. https://i.sstatic.net/V8cMj.png

The outcome would be:

https://i.sstatic.net/w5yxt.png

However, if these two types are indeed mutually exclusive, it is advisable to have two separate properties to maintain a cleaner structure.

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

Incorporating and designing a side button using jQuery Mobile

I'm working on adding a button to the left side of the screen that is round (but not necessarily) and partially visible, with a visually appealing design. This button will allow users to open a side menu panel. Below is the HTML code for the button: ...

Ensuring typescript req.user in Passport JS is always defined: Best practices

When utilizing Passport JS, the req.user within the route is considered potentially undefined. However, the middleware prior to my route method ensures that this scenario does not occur. How can I convey this information to TypeScript? Object may be &apos ...

Calculate the sum of values in a JSON array response

I recently received a JSON string as part of an API response, and it has the following structure: { "legend_size": 1, "data": { "series": [ "2013-05-01", "2013-05-02" ], "values": { "Sign Up": { "2013-05-05": 10, ...

js simulate a click on an anchor element based on the child element's id

I am trying to automatically trigger a click on an a tag that contains a div with the id='a'. $(document).ready(function() { $("#chat_list_content a:has(div[id='a'])").click(); //$("#chat_list_content a:has(div[id='a']) ...

Calling Ajax inside each iteration loop

I have encountered numerous posts discussing this topic, but the solutions I came across do not quite suit my needs. Some experts suggest changing the code structure, however, I am unsure of how to go about doing that. What I desire: 1) Retrieve a list ...

Executing processes individually within AngularJS

Just making sure I understand correctly, I have a simple web service resource query function set up like this //Get country lists $scope.getCountry = function(){ $http({ method : 'GET', url : cdnLinks('country&apos ...

JavaScript can dynamically attach EventListeners to elements, allowing for versatile and customized event

I am currently populating a table using data from an XML file. One of the columns in the table contains links to more details. Due to the unique requirements of my web page setup (Chrome extension), I need to dynamically add an event handler when the table ...

Adding or removing rows within an array in a hybrid Vue project - a step-by-step guide

Recently, I created a small web application to assist in organizing my project ideas. Check it out here: https://codepen.io/aibrindley/pen/ELXajM Now, I am working on enabling users to add items to the array directly from the interface. It would also be c ...

Combining and Filtering Arrays of Objects with Angular

I possess: arrayBefore arrayBefore = [{name:'n1', items: [i1]}, {name:'n2', items: [i2]}, {name:'n1', items: [i3]}] I desire to craft a function: myFunction myFunction(arrayBefore) In order for it to generate: arrayAfte ...

The URL dynamically updates as the Angular application loads on GitHub Pages

Encountering an unusual issue when trying to access my angular website on GitHub pages. The URL unexpectedly changes upon opening the page. Please check it out at this link: The original expected URL should be However, as the page loads, the URL gets alt ...

Error message "Undefined is not a function" occurred while using jQuery's .replace and scrollTop functions

I'm having issues with the scroll function in my code. It doesn't seem to be able to locate the ids in my HTML, even though I can't figure out why. I had a previous version that worked perfectly fine (unfortunately, I didn't save it D:) ...

How can I retrieve and manipulate the text within an option tag of a form using JavaScript?

<select name="products"> <option value=""> - Choose - </option> <option value="01">table</option> <option value="02">chair</option> <option value="03">book</option> <option value= ...

When an anchor link is dynamically created, the `click()` method does not activate the click event

After creating an anchor element using the document.createElement('a') method, I encountered an issue where the click event was not being triggered as expected. To provide more context, refer to the code snippet below: var link = document.create ...

What are the best practices for implementing optional chaining in object data while using JavaScript?

In my current project, I am extracting singlePost data from Redux and converting it into an array using Object.keys method. The issue arises when the rendering process is ongoing because the singlePost data is received with a delay. As a result, the initi ...

Sourcemaps experiencing major issues when using TypeScript and the browserify/gulp combination

Despite successfully generating sourcemaps from my build process using browserify with gulp, I encountered issues when trying to debug. Breakpoints would often jump to different lines in Chrome, indicating that the script was not pausing where it should. A ...

Even after deleting the circle from the Google Map, the label still persists within the Google Map Javascript API

Even after removing circles on the Google Map, the labels still persist. I use InfoBox to display labels on circles like this: myOptions.content = datadetail[i].Count; var ibLabel = new InfoBox(myOptions); ibLabel.open(map); I am trying to clear the circ ...

What could be the reason for the defaultCommandTimeout not functioning as expected in my script

Is there a way to wait for only one particular element in Cypress without having to add wait commands everywhere in the test framework? I've come across the solution of adding defaultCommandTimeout in the cypress.json file, but I don't want it t ...

Attempting to showcase the text within an <a> element on a <canvas> element while ensuring there are no noticeable visual distinctions

Imagine having this snippet of code on a webpage: elit ac <a href="http://www.ducksanddos/bh.php" id='link'>Hello world!</a> nunc Now, picture wanting to replace the <a> tag with a <canvas> element that displays the same ...

After updating to Angular 7, an error was encountered: "TypeError: Unable to execute map function on ctorParameters"

After updating my Angular project to version 7, I encountered a new issue. When running "ng serve --open" from the CLI, I received the following error message: Uncaught TypeError: ctorParameters.map is not a function at ReflectionCapabilities._own ...

Using Rails: How to invoke a function in the asset pipeline from a JS response?

In one of the JavaScript files I am working with, I have defined an object and a function: chosen.coffee Foo = do_this: -> $('.slider').slider() $ -> Foo.do_this() This code initializes JQueryUI to turn a specific div into a ...