Can one determine the type of an object that is inherited from another object?

I have various classes defined as follows:

export A {...} export B {...} export C {...}

export type data = A | B | C;

Next, I need to work with an array of data like this:

dataArr : Array<data> ; 

Is there a way to use something similar to type of to determine if the element inside dataArr is of type A? Or is there another method that achieves the same outcome?

Answer №1

typeof only works on primitives so it's not possible to determine the type directly. However, you can use a type guard to check if something is of type A, B, or C. Keep in mind that the complexity of the type guards may increase if there are many types for the data object.

An example of a simple type guard:

interface ImageTypeA {
    data: string
    width: number
    height: number
}

const isImageTypeA = (object: any): object is ImageTypeA => {
    return !!object.data
}

const myImage = {
    data: 'A',
    width: 1,
    height: 1
}

console.log(isImageTypeA(myImage) && myImage.data)

In this scenario (playground here), I intentionally omitted the type for myImage. Despite the lack of explicit typing, after the type guard check, the object is correctly identified as being of a specific type. When dealing with multiple types, be cautious as complex chaining can result in confusing code structure and readability issues.

Answer №2

To categorize each type, you can introduce a unique property called the discriminant property, and then differentiate the types of elements based on that property. Let's assume the structures of A, B, and C are defined as follows:

interface A  {
    name: string; 
    age: number;
    kind: "A"
};

interface B  {
    city: string; 
    state: string;
    kind: "B"
};

interface C  {
    address: string;
    kind: "C"

};

In this setup, the kind serves as the discriminant property indicating the interface type. By utilizing a switch-case statement, you can identify the different types:

type data = A | B | C;
const dataArr: Array<data> = *insert desired values here*; 

dataArr.forEach(item => {
    switch (item.kind) {
        case 'A':
            //item is of type A
            break;
    
        case 'B':
            //item is of type B
            break;
            

        case 'C':
            //item is of type C
            break;
    }
});

If A, B, and C are represented as classes:

class A  {
    name: string; 
    age: number;
};

class B  {
    city: string; 
    state: string;
};

class C  {
    address: string;
}; 

You can utilize the instanceof keyword like so:

dataArr.forEach(item => {
    if(item instanceof A){
        //item is an instance of A
    }
    if(item instanceof B){
        //item is an instance of B
    }
    if(item instanceof C){
        //item is an instance of C
    }
});

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

Whenever I am building a React application, I encounter a bug that states: "node:fs:1380 const result = binding.mkdir()"

Whenever I try to enter the command: create-react-app my-app --template typescript I keep encountering this error message: node:fs:1380 const result = binding.mkdir( ^ Error: EPERM: operation not permitted, mkdir 'D:\ ...

Ensure the information remains secure within the Ionic provider

In my Ionic 3 project, I am sending an API request and displaying the response on a page called Home.ts by using a Provider. I want to ensure that the data remains in the provider after the initial request so that all pages utilizing this Provider can acce ...

Leveraging Angular's capability to import files directly from the assets

I recently installed a library via npm and made some modifications to one of the modules. python.js If I delete the node_modules folder and run npm install, I am concerned that I will lose my changes. Is there a way to preserve these modifications by mov ...

The inserted button's click event does not trigger the contentEditable DIV

I have a contentEditable DIV that I manage using the directive below: <div class="msg-input-area" [class.focused]="isMsgAreaFocused" contenteditable [contenteditableModel]="msgText" (contenteditableModelChang ...

Tips for altering the color of the MUI table sort label icon:

Does anyone know how to change the color of the table sort label icon from gray to red? I am having trouble figuring it out. Any recommendations or suggestions would be greatly appreciated. Here is the code I have been trying to work with: <TableSortL ...

Discover the method to determine the total count of days in a given week number

I am developing a gantt chart feature that allows users to select a start date and an end date. The gantt chart should display the week numbers in accordance with the ISO standard. However, I have encountered two situations where either the start week numb ...

Mapping JSON data from an array with multiple properties

Here is a JSON object that I have: obj = { "api": "1.0.0", "info": { "title": "Events", "version": "v1", "description": "Set of events" }, "topics": { "cust.created.v1": { "subscribe": { ...

Ensure that the method is passed a negative number -1 instead of the literal number 1 from an HTML error

This is an example of my HTML code: <button (mousedown)="onMouseDown($event, -1)"></button> Here is the TypeScript code for handling the mouse down event: onMouseDown(e: MouseEvent, direction: 1|-1) { this.compute.emit(direction); ...

A problem arises when the React effect hook fails to trigger while utilizing React Context

I have created a component that is supposed to generate different pages (one for each child) and display only the selected page: import * as React from "react"; export interface SwitchProps { pageId: number; children: React.ReactChild[]; } ...

Guide on transforming an Angular 6 project into a Progressive Web Application (PWA)

Currently, my Angular 6 project is up and running smoothly. However, I am looking to integrate PWA into my existing application. When I execute the following command: ng add @angular/pwa The output displays: + @angular/<a href="/cdn-cgi/l/email-protec ...

What is the best method to adjust the width of the PrimeNG ConfirmDialog widget from a logic perspective

Currently utilizing "primeng": "^11.2.0" and implementing the ConfirmDialog code below this.confirm.confirm({ header: 'Announcement', message: this.userCompany.announcement.promptMsg, acceptLabel: this.userCompany.announcement ...

The mystery of the undefined return value in my Ionic v4 get function

I attempted to retrieve my location by saving the latitude and longitude, but my declared variable isn't returning anything. Take a look at my code snippet: public device_location: any = {}; constructor(private geolocation: Geolocation) { this.s ...

Unleashing the Potential of a Single Node Express Server: Hosting Dual Angular Apps with Distinct Path

I have successfully managed to host two separate angular applications (one for customers and one for company staff) on the same node server, under different paths. The setup looks like this: // Serve admin app app.use(express.static(path.resolve(__dirname, ...

Is there a way to conceal 'private' methods using JSDoc TypeScript declarations?

If we consider a scenario where there is a JavaScript class /** * @element my-element */ export class MyElement extends HTMLElement { publicMethod() {} /** @private */ privateMethod() {} } customElements.define('my-element', MyElement) ...

What is the best way to disable a submit button based on form validity in Angular 4 with ng-content?

Include a form component that consists of an email field, password field, and submit button passed through ng-content. This allows the login form to display a 'Login' button and the register form to display a 'Register' button. Here is ...

Exploring Node Stream.Writable Extension in Typescript 4.8

I'm attempting to craft a basic class that implements Node stream.Writable, but it seems like I can't quite grasp the correct syntax - the compiler keeps throwing errors: https://i.stack.imgur.com/UT5Mt.png https://i.stack.imgur.com/Z81eX.png ...

Yep, implementing conditional logic with the `when` keyword and radio buttons

I seem to be encountering an issue with my implementation (probably something trivial). I am utilizing React Hook Form along with Yup and attempting to establish a condition based on the selection of a radio group. The scenario is as follows: if the first ...

Why is the return type for the always true conditional not passing the type check in this scenario?

Upon examination, type B = { foo: string; bar: number; }; function get<F extends B, K extends keyof B>(f: F, k: K): F[K] { return f[k]; } It seems like a similar concept is expressed in a different way in the following code snippet: functi ...

Definition file for Typescript d.ts that includes optional properties in a function

Within my code, I have a function that offers different results based on specified options. These options dictate the type of return value. The function is currently written in plain JavaScript and I am looking to provide it with types using an index.d.ts ...

Modify data in a table using Dialog Component in Angular Material

I need to implement a Material Dialog feature that allows users to update entries in a table by clicking on the "Change Status" button. Check out this functional snippet: https://stackblitz.com/edit/angular-alu8pa I have successfully retrieved data fr ...