When working with a union type in TypeScript, it is important to note that the property may

Imagine a scenario where I am dealing with two specific interfaces:

interface Box {
    x: number
    y: number
}

and

interface ColouredBox {
    x: number
    y: number
    colour: string
}

For the sake of this discussion, let's assume that the interfaces cannot be modified.

When it comes to creating objects, the code I typically use looks something like this:

let a: Box|ColouredBox = {x: 1, y: 2}
if( something ){
    a.colour = "Blue"  // Compilation Error
}

Attempting to assign a value to a.colour = "Blue" results in the following error:

Error:(24, 26) TS2339: Property 'colour' does not exist on type 'Box'.

What is causing this error? Is this a limitation of the TypeScript compiler? Are there any alternative approaches I could take without completely rebuilding the object?

Answer №1

To check for the existence of a property, you can utilize the in type guard:

if ("color" in obj) {
    obj.color = "Blue" // This will work
}

Using this method, you can narrow down to the specific union type ColoredBox based on whether the property color exists. Keep in mind that you can only access common properties like x and y of Box | ColoredBox if they haven't been narrowed down before.

Check out this live code sample for a demonstration.

Answer №2

Optimizing with Partial Types

Instead of utilizing a union type, an alternative approach is to make use of the Partial type

let a: Partial<ColouredBox> = {x: 1, y: 2}

By using Partial, all properties of the ColoredBox become optional.

For a hands-on demonstration, check out the live example here.

Update:

Simplify with Elimination of an Interface

To make only the color part of the interface optional, consider decreasing the number of interfaces.

interface Box {
  x: number;
  y: number;
  color?: string;
}

To check if you're working with a colored box:

if (box.color) { ... }

Explicit Type Casting

If utilizing both interfaces is necessary, you can specifically specify a as a ColouredBox using the as keyword, which is known as Type Casting.

let a: Box | ColouredBox = { x: 1, y: 2 };
(a as ColouredBox).colour = "Blue";

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

Encountering the "Argument of type 'string' is not assignable to parameter of type 'never'" error when using Array.prototype.includes

The data type for keys is a combination of string[] | number[], which is derived from the ID type. The data type for id is simply ID. We want to check if the id exists within the array of keys. import React, { useState } from 'react'; type Distr ...

typescript unconventional syntax for object types

As I was going through the TypeScript handbook, I stumbled upon this example: interface Shape { color: string; } interface Square extends Shape { sideLength: number; } var square = <Square>{}; square.color = "blue"; square.sideLength = 10; ...

Search through an array of objects and assign a new value

I am facing a challenge with an array of objects structured as shown below: [ { "e_id": "1", "total": 0 }, { "e_id": "3", "total": 0 } ] My objecti ...

Using an external variable within an internal function in TypeScript

I am facing a situation where I have a variable outside of a function that needs to be updated, but I am unable to access it using "this" as it is not reachable at that point in the code. export class GamesDetailPage { details : any = {}; type : St ...

Trouble arises from the object data type not being properly acknowledged in TypeScript

In the code snippet provided, I am facing a challenge where I need to pass data to an if block with two different types. These types are handled separately in the if block. How can I make TypeScript understand that the selected object could be either of ty ...

VS Code failing to refresh TypeScript in Vue files

Currently, I'm using Vue with Vue Single File Components (SFC) and TypeScript in vscode. However, I've noticed that the types I create in a .d.ts file are not being applied or updated in my .vue files. It's only when I reload the window that ...

The service remains operational while the button's status undergoes a change

In my data table, each row has a column containing buttons. To ensure that only the button in the clicked row is executed, I include the index of that row in the start/pause timer function. I decided to create these functions in a service so that the time ...

What is the process in TypeScript for defining a custom variation of a generic function?

Suppose we have a generic function: const f1 = <T>(x: T) => console.log(x) We can then create a specialized version for f1, like this: const f2 = (x: number) => f1(x) If we try to call f2 with an argument of type string, TypeScript will thr ...

Utilizing statuses in Typescript React for conditional rendering instead of manually checking each individual variable

It's common for developers, myself included, to perform conditional rendering by checking variable values like this: import React, { useState, useMemo } from 'react' const Page = () => { const [data, setData] = useState<any[]>() ...

Retrieving specific properties from a JSON object and logging them

I am attempting to access JSON Object properties directly and log them using the following function : loadProcesses(filter?){ this._postService.getAllProcess(filter) .subscribe( res=> { this.processListe = res; // console.log(this.p ...

Tips for specifying a variable as a mandatory key attribute within an array

Is there a way to dynamically determine the type of key attribute in an array? const arr = [ { key: 'a' }, { key: 'b' }, { key: 'c' }, ]; type key = ??? // Possible values for key are 'a', 'b', or &a ...

mobx: invoking a class method upon data alteration

Is it possible to utilize the Mobx library in order to trigger a class method whenever data changes? For instance, when MyObject assigns a value of 10 to container['item'], can we have the myaction method invoked? class MyElement extends Compone ...

Tips for populating class attributes from an Angular model

Suppose there is a Class Vehicle with the following properties: public id: number; public modelId: number; public modelName: string; Now consider we have an object that looks like this {id: 1, modelId: 1, modelName: "4"} What is the best way to assign e ...

What is the best way to retrieve a cookie sent from the server on a subdomain's domain within the client request headers using getServerSideProps

Currently, I have an express application using express-session running on my server hosted at api.example.com, along with a NextJS application hosted at example.com. While everything functions smoothly locally with the server setting a cookie that can be r ...

A destructured object with a Typescript interface

While working on a React / TypeScript project, I encountered an error involving destructuring an object. The issue arises when I try to destructure notificationData within the publish function. An error message stating "Property 'messages' does ...

"Although the NextJS client-side data is present, it seems to be struggling to

I am facing an issue while trying to display fetched data on a blog page. Although the data is successfully retrieved client-side and I can view it using console.log(), it does not appear on the page and the elements remain empty. I am completely puzzled. ...

ng serve issue persists even after resolving vulnerabilities

Can anyone assist me in resolving why I am unable to start my project after fixing 3 high vulnerabilities? I ran npm audit to identify the vulnerabilities and then used npm install --save-dev @angular/<a href="/cdn-cgi/l/email-protection" class="__cf_em ...

Tips for synchronizing response JSON with TypeScript interface in Angular 6

I am retrieving a list of files that have been uploaded from a backend endpoint, and it comes back in this format: [ { "filename": "setup.cfg", "id": 1, "path": C:\\back-end\\uploads\\setup.cfg", ...

Struggle between Angular and fundamental CSS principles

Upon following the steps below, I aim to achieve my desired grids: How to set auto-margin boxes in flexible-width design using CSS? The solution provided is effective when implemented outside of Angular. However, when inserted inside an Angular component ...

Opening a modal from a different component in Angular 6

I am attempting to launch a modal that is associated with a separate component. However, I encountered an error ERROR TypeError: Cannot read property 'show' of undefined Here is my code: product-catalog.component.html <app-cart-table-modal& ...