Creating a TypeScript constructor for the parent class that accesses the properties of the child class

abstract class Parent {
  public foo: string;

  constructor(v: Partial<Parent>) {
    Object.assign(this, v);
  }
}

class ChildA extends Parent {
  bar: string;
}

class ChildB extends Parent {
  baz: string
}

In this scenario,

const a = new ChildA({ foo: 'foo', bar: 'bar'});

An error occurs:

TS2345: Argument of type '{ foo: string; bar: string }' is not assignable to parameter of type 'Partial<Parent>'.
Object literal may only specify known properties, and 'bar' does not exist in type 'Partial<Parent>'.

The use of

constructor<T extends Parent>(v: Partial<T>)
also fails. (TS1092: Type parameters cannot appear on a constructor declaration.)

Is there a way to define the constructors of classes Parent, ChildA, and ChildB in a type-safe manner?

Answer ā„–1

If you wish to utilize the polymorphic this type within constructor parameters, you will face limitations.

Regrettably, TypeScript does not support this functionality by default as indicated in microsoft/TypeScript#5449. There have been related discussions and feature requests which highlight this constraint. As of now, there is no straightforward way to specify that the constructor parameter should be dependent on the type of the current class constructor for inheritance in subclasses.

If you require such behavior, TypeScript does not offer it out-of-the-box; instead, you will need to find a workaround.


Polymorphic-this involves "implicit" F-bounded polymorphism, treating this like a generic type parameter constrained to itself. Since implicit functionality is unavailable for constructor parameters, one possible solution is to add a self-bounded type parameter to the class explicitly:

abstract class Parent<T extends Parent<T>> {
    public foo: string = "";

    constructor(v: Partial<T>) {
        Object.assign(this, v);
    }
}

This approach works by constraining the type parameter T to Parent<T> within Parent<T>, allowing the use of T in place of this. When defining subclasses, explicit declarations are required:

class ChildA extends Parent<ChildA> {
    bar: string = "";
}

class ChildB extends Parent<ChildB> {
    baz: string = ""
}

Now, your subclasses will function as intended:

new ChildA({ foo: 'foo', bar: 'bar' }).bar;

To simplify referencing Parent elsewhere in your codebase, you may consider assigning a default value to T. Several options exist depending on your preference for convenience versus precision. You could opt for any for maximum convenience, followed by more defined defaults like Parent<any> and further iterations such as Parent<Parent<any>>. For extreme accuracy, an option with never may help identify incorrect uses of Parent where only concrete subclasses make sense.

It is advisable to evaluate these options against your specific requirements to determine the most suitable choice.

Playground link to code

Answer ā„–2

I believe the typescript error is accurate

The Parent only contains the foo: string variable

If you want to create a new instance of ChildA, you must define a constructor within ChildA to ensure the correct type is passed from external sources

abstract class Parent {
    public foo: string;

    protected constructor(v: Partial<Parent>) {
        Object.assign(this, v);
    }
}

class ChildA extends Parent {
    bar: string;
    constructor(v: Partial<ChildA>) {
        super(v);
    }
}


const a = new ChildA({ foo: 'foo', bar: 'bar'});

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

The process of linking a Json response to a table

In my products.components.ts class, I am retrieving Json data into the variable this.Getdata. ngOnInit() { this._service.getProducts(this.baseUrl) .subscribe(data => { this.Getdata=data this.products=data alert(JSON.stringify(this.Getdata)); ...

Tips for showing an image through a button in Angular 4

Currently, I am in the process of creating a simple website and I have encountered an issue. When I click on a button to display an image, it works fine. However, when I click on another button to display a different image, the previous image remains visib ...

What steps are necessary for TypeScript to retrieve my definitions when utilizing node.js require statements?

I have been utilizing Visual Studio 2013 tools for Node.js along with VS2013 Update 2. In my util.ts file, I have the following code: var Util = function () { this.getSelectOption = function (elem, value) { var x = 99; } module.exports = ...

Checkbox Event Restricts Access to a Single Class Variable

As a beginner in AngularJS (just diving in this week), I've encountered an issue with a checkbox input connected to an ng-change event. <input type="checkbox" ng-model="vm.hasCondoKey" ng-change="vm.onKeyCheckboxChange()" /> The ng-change even ...

Function in Typescript used for checking types and catching compilation errors from external sources

Fact: I am currently using TS version 2.3.4. I have developed a function that checks if a variable is defined (it takes the parameter variable and returns 'undefined' !== typeof variable). It's quite simple. export function IsDefined(variab ...

Is conditional compilation possible with ifdef-loader in combination with Angular 13 and Webpack?

My application built with Ionic heavily relies on conditional compilation, where I need to include or exclude code blocks based on specific config values, similar to the functionality of m4. Previously, I successfully utilized https://github.com/nippur72/ ...

There was a TypeError encountered when trying to access the property 'Symbol(Symbol.iterator)' of an undefined variable

Whenever a web service request fails, this exception is thrown: TypeError: Cannot read property 'Symbol(Symbol.iterator)' of undefined Specifically, the HTTP GET request returns a 400 Bad Request error. Below is the component involved in this ...

Angular 2 TypeScript: How to effectively sort an array

Iā€™m currently exploring how to implement array filtering in Angular 2 with TypeScript. Specifically, I am trying to filter data for a search bar in Ionic 2. While the list in the template successfully displays the data, I am encountering difficulty getti ...

Circular structure error occurred when attempting to convert an object to JSON, starting at an object constructed with the constructor 'Object'

I am facing an issue where I need to update a Medico from the collection, and I have successfully destructured the data of the Medico's name and email. Additionally, I have obtained the ID of the assigned hospital. However, I am having trouble sendin ...

Angular is unable to fetch the chosen option from a dropdown selection

Recently, I encountered an issue with a module form that appears as a pop-up. Within this form, users can input data required to create a new object of a specific class. One field allows users to select a ventilation zone for the new room object being crea ...

Navigating through a mergeMap observable with an undefined value

In my Angular 6 app, I have a class that attaches API tokens to every http request using the getIdToken() method. If the token retrieval is successful, everything works fine. However, if it fails, my app will stop functioning. I need help with handling th ...

Utilizing React-hook-Form to transfer data between two SelectBoxes

This simple logic is causing me some trouble. Despite using react-hook-form, I thought this would be easy. However, after struggling with it for over a week, I'm still facing challenges. I'm incorporating nextUI components into my project. < ...

Angular 8 throws a TS2339 error, yet the code is functioning perfectly and delivering the desired output

Upon compiling my code, I encountered the following error: ERROR in src/app/home/home.component.ts:13:37 - error TS2339: Property 'name' does not exist on type 'string | Type'. Property 'name' does not exist on type &ap ...

Exploring alternative methods for accessing object values in TypeScript using a string object path without relying on the eval function

If we have an object in JS/typescript structured like this: var obj = { a: { b:{ c:1 } } } And a string "b.c" is given, how can we evaluate this using only the variables provided and retrieve the value 1 from the object without rel ...

When ngIf fails to detect a change in a variable's value

Whenever I try to set a simple boolean variable to show/hide a div from another component, the ngIf directive doesn't seem to recognize it. In my messages-refresh.component.html file: <div class="divOpacity" *ngIf="show"> <div class="boxMes ...

What is the best way to create a React component that renders a class component as a functional component?

My Objective: At the moment, I am in the process of developing an AuthUserRole HOC component to manage user roles like Manager and Employee. However, I encountered a tutorial that uses a functional component to return a class component as referenced here. ...

The error message related to TupleUnion in TypeScript is indicating that the depth of type instantiation may be too deep and could

Recently, I've been delving into a TypeScript utility type known as TupleUnion. This useful type came to my attention through a fascinating Twitter post, and I've observed it being utilized in various Stack Overflow solutions. Here's how the ...

When trying to ctrl-click on paths in Visual Studio Code, the resolution is incorrect

I'm currently working on customizing a library by modifying its source code. I've downloaded the source code and now I'm trying to configure vscode, typescript, and webpack to recognize that file. Although I've successfully aliased the ...

`Utilizing Symbolic Links to Share Code Across Multiple React Applications`

Presently, I have developed two distinct frontend applications. One is a lightweight mobile client, and the other is a heavy administration panel. Both of these were built using Create React App (CRA), utilizing TypeScript throughout. The current director ...

Issues arise when Typescript's declaration merging feature does not function correctly when utilizing ts-node

I am currently working on a project that involves using the express-session package. My goal is to modify the session object by adding a user key. req.session.user = 123; After reading through the accepted answer in this question, I learned about declarat ...