The property X within the ClassB type cannot be assigned to the identical property within the parent type ClassA

I deal with the following set of Typescript classes:

  1. Firstly, we have an abstract class

    export abstract class MyAbstractClass {
        ...
    }
    
  2. Next is Class A which implements the methods from the abstract class

    export ClassA extends MyAbstractClass {
    
        readonly MY_FIRST_CONST = 'blaa';
        readonly MY_SECOND_CONST = 'blaablaaa';
    
        ...
    }
    
  3. Then, there's class B which extends class A and aims to override the value of MY_FIRST_CONST. No other changes have been made in the implementation

    export ClassB extends ClassA {
    
        readonly MY_FIRST_CONST = 'other blaa';
        readonly MY_SECOND_CONST = 'other blaablaaa';
    
        ...
    }
    

When working on ClassB, I keep encountering the same error message at the line pertaining to MY_FIRST_CONST:

   Property 'MY_FIRST_CONST' in type 'ClassB' is not assignable to the same property in base type 'ClassA'.

The error states: Type ""other blaa"" is not assignable to type ""blaa"".

I'm puzzled by the occurrence of this error, especially since it doesn't occur with MY_SECOND_CONST. Any insights or ideas on how to resolve this?

Answer №1

You seem to be facing a design dilemma. The issue lies in the fact that you are attempting to override a readonly attribute in a subclass, which is not logically consistent.

If you intend for subclasses to have the ability to modify the value, then it should not be declared as readonly. On the other hand, if you do not want subclasses to change the value, then it should not have a different value in the subclass.

However, there may be a scenario where you want subclasses to define a value that remains unchangeable after instantiation. This can be achieved either through a proper constructor implementation or by utilizing getters:

Using a constructor:

export class ClassA extends MyAbstractClass {

  readonly foo;

  constructor(foo = 'foo') {
    super();
    this.foo = foo;
  }
}

export class B extends ClassA {

  constructor() {
    super('bar')
  }
}

Using getters:

export class ClassA extends MyAbstractClass {
  get foo() {
    return 'foo';
  }
}

export class B extends ClassA {
  get foo() {
    return 'bar';
  }
}

Answer №2

Upon receiving that particular error message, it appears that the issue lies in how the compiler is interpreting the properties of your class A. It seems to be treating them as specific strings rather than just a generic string type, hence the error message indicating that the "string" is not compatible with the only allowable string value.

You can verify this by hovering over the property MY_FIRST_CONTS and observing that TypeScript is identifying the type as "blaa" instead of "string".

If we explicitly specify the types of MY_FIRST_CONTS and MY_SECOND_CONTS as string, the problem is resolved without any additional issues.

export abstract class MyAbstractClass {
}

class ClassA extends MyAbstractClass {
  readonly MY_FIRST_CONTS: string = 'blaa';
  readonly MY_SECOND_CONTS: string = 'blaablaaa';
}

class ClassB extends ClassA {
  readonly MY_FIRST_CONTS = 'other blaa';
  readonly MY_SECOND_CONTS = 'other blaablaaa';
}

Try it out on the TypeScript Playground

Answer №3

The problem here lies in the design - it is crucial for class B to inherit from the base, in the same way that class A does.

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

Angular2 material dropdown menu

Currently, I am studying angular2 with its material design. One of the modules I am using is md-select for material and here is a snippet of my code: <md-select> <md-option value="1">1</md-option> <md-option value="2">2< ...

Conditional type in Typescript can be used to infer tuple types

Why are output1 and output2 not both inferred as [number, number, number] in the following code snippets? Snippet 1 : type InferTuple1<T> = T extends any[] ? [...T]: never; const func1 = <T>(t: InferTuple1<T>) => t; const output1 = ...

Tips for splitting JSON objects into individual arrays in React

I'm currently tackling a project that requires me to extract 2 JSON objects into separate arrays for use within the application. I want this process to be dynamic, as there may be varying numbers of objects inside the JSON array in the future - potent ...

Is Angular 2 giving you trouble with the AoT compilation and module.id error?

I need to set up AoT compilation for my Angular 2 project. My application is organized into a js directory where all generated .js files are stored, and an app directory containing my .ts, .html, and .css files. For the AoT compilation process, I am usin ...

Challenges with variable scopes and passing variables in Ionic 2 (Typescript)

In my Ionic 2 TypeScript file, I am facing an issue with setting the value of a variable from another method. When I close the modal, I get undefined as the value. I'm encountering difficulty in setting the value for coord. export class RegisterMapP ...

How can the id from a post response be obtained in Angular 7 when using json-server?

When utilizing the http options below: const httpOptions: any = { headers: new HttpHeaders({ 'Content-Type': 'application/json' }), observe: 'response' }; I execute an http post to a json-server endpoint like this: ...

Guide on validating multiple preselected checkboxes using Angular 8 reactive forms

I have a problem with validating checkboxes in my Angular application. The checkboxes are generated dynamically from an array using ngFor loop, and I want to make sure that at least one checkbox is selected before the form can be submitted. The validatio ...

ngClass with multiple conditions

I am currently working on implementing the following functionality - I have two pre-set classes that are combined with some component variables successfully. However, I now need to include an additional conditional class. Although the first part is functi ...

Setting up an angular2 web application on an Nginx server and forwarding HTTP requests to the backend API for

Seeking assistance with setting up angular2 routes and proxying http requests to a rest api on a separate server Currently, I have an angular2 web application running on an nginx server which serves the static html files. The rest api that the application ...

Employing async/await for efficient data retrieval

Attempting to utilize async-await in TypeScript Vue 3 to retrieve data, but encountering an issue where the function is already logging 'undefined' (or executing before the function call) private async exportDataOrder() { await this.getDataEx ...

Issue detected: Props that are of type Object/Array must utilize a factory function in order to provide the default value

I recently started using Vue-Cli3.0 and came across this interesting module for Vue.js called https://github.com/holiber/sl-vue-tree It's a customizable draggable tree component for Vue.js, but I encountered an issue where it couldn't copy funct ...

Creating a unique Tag Name for Dynamic Components in Angular

I want to customize a component @Component({ selector: '[my-component]', template: `<i>1</i><p>content</p><b>2</b>` }) export class MyComponent { public tagName: string; } Then there's another comp ...

Unable to assign unique identifiers to elements within a user interface framework

I am having difficulty assigning an id to components. Scenario 1: - Trying to assign an id to an HTML component. <h1 id="demo-h1">Demo Heading</h1> Assigning id to HTML component Scenario 2: - Attempting to assign an id to a componen ...

Exploring proactive search using RxJS Observable compared to Subject

Two different methods have been presented for tackling the same issue, which is to conduct a real-time search for specific characters entered by the user in a text box. The first solution is derived from the ngrx example, while the second solution is from ...

Using Pipe directive in Angular 2 with ES5: Error - Directive annotation missing from constructor

My simple pipe looks like this: app.DisplayKeystrokePipe = ng.core .Pipe({ name: "displayKeystroke" }) .Class({ transform: function() { } }); On the other hand, I have a more complex component/directive: app.Drop ...

Exploring TypeScript to get a ref with the Vue Composition API

The issue I'm facing is related to Vetur underlining 'null' in the following line: const firstRef = ref<HTMLElement>(null) <template> <input id="first" ref="firstRef"> <button type="button&q ...

What is the best way to compare dates for a deadline using Angular and CSS?

Having recently delved into Angular 8, I just picked up on how to convert timestamps to strings using interpolation and .toMillis. However, I am looking to enhance this feature in my project app. I'm currently working on comparing the date saved in m ...

"Troubleshooting: Why Angular2's ngOnChanges is not triggering with array input

I am currently using a ParentComponent to pass inputs to a ChildComponent. When the input is a number, the ngOnChanges hook successfully fires. However, when it's an array, the hook does not trigger. Could someone help me identify what I might be doi ...

Personalized Carousel using Ng-Bootstrap, showcasing image and description data fields

I have been working on customizing an Angular Bootstrap Carousel and have managed to successfully change the layout. I now have two columns - with the image on the right and text along with custom arrows on the left. My goal is twofold: First, I am lookin ...

Utilizing web components in React by solely relying on a CDN for integration

I have a client who has provided us with a vast library of UI elements that they want incorporated into our project. These elements are stored in javascript and css files on a CDN, and unfortunately I do not have access to the source code. All I have at my ...