TypeScript: Defining a parent class type for its children

Dilemma

I am seeking a way to structure a JSON object containing three different types of objects, all derived from the same parent object. Additionally, I wish to designate their specific types for improved Intellisense functionality within my codebase when utilizing functions from the parent class...

Illustration:

abstract class Parent{
    function do_something() {...}
}

class child_1 extends Parent{}
class child_2 extends Parent{}
class child_3 extends Parent{}

// The JSON Structure
const json: {[key: string]: /*NEED HELP WITH WHAT_TO_PUT_HERE*/} = {
    'child_1': child_1,
    'child_2': child_2,
    'child_3': child_3,
}

Answer №1

When you mention a "JSON object," I assume you are referring to a JavaScript object, as seen in your example code. It appears that each value within the object should be an instance of one of the child classes rather than the class itself.

TypeScript should automatically deduce the type of your json object. If your editor is configured to use TypeScript's language server, you will receive suggestions for methods on each value in the object through IntelliSense.

Below is a refined version of your example to illustrate this:

abstract class Parent {
  parentMethod() {}
}

class Child1 extends Parent {
  child1Method() {}
}

const children = {
  child1: new Child1(),
};

// You can access both `parentMethod` and `child1Method` using Intellisense
children.child1.parentMethod();
children.child1.child1Method();

If you want to ensure that every value in the object is a type of Parent, you can define it like this:

const children: { [index: string]: Parent } = {
  child1: new Child1(),
  child2: new Child2(),
  child3: new Child3(),
};

By doing this, you will only have access to the methods from Parent on the property named child1. This restricts the properties to being treated as instances of Parent rather than specific child classes.

If you prefer not to broaden the type of each property to Parent, you can specify the index type as a union of all possible children:

const children: { [index: string]: Child1 | Child2 | Child3 } = {
  child1: new Child1(),
  child2: new Child2(),
  child3: new Child3(),
};

Using this method allows you to call methods from Parent on any property of the object. However, you will need to utilize a type guard to determine which specific class each property belongs to before utilizing any methods unique to a particular child class.

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

Guide on Validating Several Email Addresses in a React Form using Angular 4

I need to input 50 email addresses with the same domain name (gmail.com). Currently, I am using a Reactive form but the code I have implemented is not working as expected. https://stackblitz.com/edit/angular-wfwfow If anyone could assist me with this, I ...

calculating the sum of all individual items within an object

Is there a way to map an object, add specific values, and then calculate the total? I am looking to map the object below and extract certain items. Any suggestions? Object: [ { "description": "Current Term", " ...

How can an additional value be sent to the form validation method?

I have created a form group like this: import { checkPasswordStrength } from './validators'; @Component({ .... export class PasswordComponent { ... this.userFormPassword = this.fb.group({ 'password': ['', [ ...

What could be the reason for the title template not being implemented in the Next.js metadata for my homepage?

Currently, I am in the process of developing a Next.js project and working on setting dynamic metadata for various pages. Specifically, I want to display the title of my homepage as "Home | My Website", but unfortunately it is only showing as "Home". Below ...

Using Regular Expressions: Ensuring that a specific character is immediately followed by one or multiple digits

Check out the regular expression I created: ^[0-9\(\)\*\+\/\-\sd]*$ This regex is designed to match patterns such as: '2d6', '(3d6) + 3', and more. However, it also mistakenly matches: '3d&apos ...

Using TypeScript to create a list of key-value pairs, which will be converted into a list of objects

Is there a more elegant way to transform an array of key-value pairs into a list of objects in TypeScript? let keys : string [] = ["name", "addr", "age"]; let values : string [][] = [["sam", "NY", "30"],["chris", "WY", "22"],["sue", "TX", "55"]]; The desi ...

Angular Navigation alters the view

I want to navigate to a different page using Angular routing, but for some reason it's not working. Instead of moving to the designated Payment Component page, the content is staying on my Main Component. Why is this happening? app.routing.module.ts ...

What is causing this error? The length of this line is 118 characters, which exceeds the maximum allowed limit of 80 characters for max-len

I am encountering issues while attempting to upload my function to Firebase, specifically receiving two errors as follows: 39:1 error This line has a length of 123. Maximum allowed is 80 max-len 39:111 warning 'context' is defined but ...

Exploring Composite Types with TypeScript's `infer` Keyword

After implementing redux in my project, I found myself including the following code snippet in my store: type CombinedParamTypes<T extends { [key: string]: (state: any, action: any) => any; }> = T extends { [key: string]: (state: infer R, ...

Tips for retrieving a date and time selection from a mat-date-picker and mat select?

I am currently utilizing Angular calendar to display various events. Each event is defined by the following parameters: event:{ title: string, start: Date, end: Date }; As material design does not offer a date-time picker, I have opted for usi ...

Utilizing React MUI Autocomplete to Save Selected Items

Exploring the realms of React and TypeScript, I find myself puzzled by a task at hand. It involves storing user-selected options from an Autocomplete component and subsequently sending these values to an external API. Is there a recommended approach for ac ...

How to generate a SAS token or URL for a blob in React?

Hey there! I'm working on a React app that's written in TypeScript. I need to retrieve the document name as a query parameter and then get the SAS URL of the document for additional processing. Do you have any suggestions on how I can accomplish ...

Giving angularjs components access to controllers

I am currently working on implementing a specific behavior using AngularJS components. <parent-component> <reusable-child-component></reusable-child-component> </parent-component> My goal is to pass the parent's controller ...

Exploring Immediately Invoked Function Expressions in TypeScript

I came across an interesting article on self-invoking functions in JavaScript by Minko Gechev. This article teaches us how to create a JavaScript function that calls itself immediately after being initialized. I am curious about how we can achieve this in ...

Is it considered an anti-pattern in TypeScript to utilize BehaviorSubject for class or object properties?

When working with Angular, I find myself frequently displaying members of classes in an Angular HTML template. These classes often share common members structured like this: class Foo { bar: string; bas: Date; } There are instances where I need to ...

Store Angular 17 control flow in a variable for easy access and manipulation

Many of us are familiar with the trick of "storing the conditional variable in a variable" using *ngIf="assertType(item) as renamedItem" to assign a type to a variable. This technique has always been quite useful for me, as shown in this example: <ng-t ...

Using Array.push within a promise chain can produce unexpected results

I have developed a method that is supposed to retrieve a list of devices connected to the network that the client has access to. export const connectedDevicesCore = (vpnId: string, vpnAuthToken: string) => Service.listVPNConnectionsCore ...

Error: The function was expecting a mapDiv with the type of Element, but instead undefined was passed - google

I have a map within a div tagged with #mapa. Whenever I try to plot a route on the map, it refreshes. I don't want the map to refresh, and here is the code I currently have: <div style="height: 500px; width: auto;" #mapa> <google-map heigh ...

When conducting tests, TypeScript raises an issue when comparing the values of array elements subsequent to performing a shift()

I am working with an array of strings, which was created by splitting a larger string using the `split` operation. Specifically, I am performing some tests on the first two elements of this array: var tArray = tLongString.split("_") if (tArray[0] == "local ...

Sorting and dividing an Array using Angular

Forgive me in advance if this sounds like a naive question, as Angular and Typescript are not my strong suits. I am assisting a friend with an issue that I can't seem to overcome. I have an array of players that includes details such as first name an ...