What steps can be taken to resolve the error message "Property does not have an initializer and is not definitively assigned in the constructor"?

I'm encountering an issue with these classes. I want to utilize the doSomething() method that is exclusive to class B without having to type cast it each time. However, when I specify property a to be of type B, it gives me an error saying it's not assigned in the constructor, even though the parent constructor handles the assignment.

class A {

}

class B extends A {
  doSomething() { }
}

class One {
  constructor(protected a: A){  }
}

class Two extends One {
  protected a: B // Property 'a' has no initializer and is not definitely assigned in the constructor.

  constructor(){
    super(new B());
    // If I add "this.a = new B();" here, the error disappears but it seems redundant.
  }

  doStuff() {
    this.a.doSomething()
  }
}

What am I doing incorrectly?

Playground

Answer №1

The issue lies in the discrepancy between the proposed addition of class field declarations to JavaScript and what was anticipated by TypeScript developers when incorporating them into TypeScript. It appears that in JavaScript, class field declarations are initialized using Object.defineProperty() rather than simple assignment. Additionally, any declared fields without initial values will default to undefined. Consequently, your code may inadvertently result in setting a as undefined in the subclass, even though your intention was merely to refine the type from the base class.

Hence, TypeScript 3.7 introduced a new flag, `--useDefineForClassFields`, along with the `declare` property modifier to align with the expected semantics of Object.defineProperty() for class fields:

If you utilize `--useDefineForClassFields`, the compiler will generate code that conforms to the specified behavior of Object.defineProperty() for class fields:

By running your code with this flag enabled, you will observe the runtime issue:

new Two().doStuff()
// [ERR]: "Executed JavaScript Failed:" 
// [ERR]: this.a is undefined 

To resolve this, employ the `declare` property modifier to narrow down the subclass property without emitting corresponding Object.defineProperty() instructions:

class Two extends One {
  declare protected a: B // okay

  constructor() {
    super(new B());
  }

  doStuff() {
    this.a.doSomething()
  }
}

new Two().doStuff(); // operation successful now

Clickable link to the playground featuring the code

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

What could be the reason for the tsc command not displaying compilation errors when compiling a particular file?

My file, titled app.ts, contains the following code snippet: interface Foo { bar:String; } const fn = (foo? :Foo) => foo.bar; When I run tsc from the root folder with strict:true in my tsconfig.json file, I receive an error message like this ...

Angular 12: TypeScript Issue TS2339 - Unable to Locate Property on Type

Whenever I use the code below, I encounter error TS2339: Property 'timestamp' does not exist on type 'LogRepair[]' In the component's HTML file, I am attempting to loop through an array of properties defined in the LogRepair typ ...

TypeORM: When generating a migration, a SyntaxError is thrown stating that an import statement cannot be used outside a

While configuring TypeORM in my NextJS TypeScript project, I encountered an issue where I received the error message: SyntaxError: Cannot use import statement outside a module when attempting to create migrations for my entities. ...

I encountered an issue with my autocomplete feature in Angular TypeScript where it was returning a [object Object] value

Issue with autocomplete displaying [object Object] value in Angular TypeScript I'm having trouble pinpointing the exact problem HTML snippet <mat-form-field style="margin-right: 10px;"> <input #productName matInput placeholder="Product" ...

Angular - delay execution until the variable has a value

When the ngOnInit() function is called, the first line of code retrieves a value from local storage which is then used to filter data from the database. Both actions happen simultaneously, resulting in an issue where I don't receive the expected resu ...

Why does the data appear differently in Angular 9 compared to before?

In this particular scenario, the initial expression {{ bar }} remains static, whereas the subsequent expression {{ "" + bar }} undergoes updates: For example: two 1588950994873 The question arises: why does this differentiation exist? import { Com ...

Angular routing is failing to redirect properly

After creating a sample Angular app, the goal is to be redirected to another page using the browser URL http://localhost:1800/demo. The index.html file looks like this: <!doctype html> <html lang="en"> <head> <title>Sample Ang ...

Loop through the array while handling a promise internally and ensure completion before proceeding

I am currently working on populating a response array with Firestore snapshots and creating download links for stored files within each snapshot. Despite trying various solutions involving Promises, the response array consistently ended up being null. do ...

The types 'X' and 'string' do not intersect

I have a situation where I am using the following type: export type AutocompleteChangeReason = | 'createOption' | 'selectOption' | 'removeOption' | 'clear' | 'blur'; But when I try to compress the cod ...

Transform Promise-based code to use async/await

I'm attempting to rephrase this code using the async \ await syntax: public loadData(id: string): void { this.loadDataAsync() .then((data: any): void => { // Perform actions with data }) .catch((ex): v ...

Exploring the benefits of leveraging TypeScript with AWS NodeJS for improved stacktrace visibility over traditional JavaScript

I'm contemplating the idea of transitioning my existing JavaScript codebase to incorporate TypeScript in NodeJS. One aspect that I am concerned about is being able to view the stack trace in AWS CloudWatch (request log) in case an error occurs during ...

Consistently scaling the Embla carousel slides for a seamless presentation experience

In my current project, I am utilizing Embla Carousels and aiming to incorporate a smooth slide scaling effect as users scroll through. The idea is for slides to enlarge the closer they get to the left edge of the carousel container, then decrease in size r ...

The type 'Dispatch<SetStateAction<boolean>>' cannot be assigned to type 'boolean'

Currently, I am attempting to transfer a boolean value received from an onChange function to a state variable. let [toggleCheck, setToggleCheck] =useState(false);` <input type="checkbox" id={"layout_toggle"} defaultChecked={toggleCh ...

What's the best way to reset the `react-google-recaptcha` checkbox in a redux application following the submission of a form?

My Redux application consists of two files: LoginForm (which contains the form elements) and LoginFormContainer (which manages form values using Formik). I am facing an issue with resetting the captcha, as the ref is located in the LoginForm file. I attemp ...

Instructions on invoking a function from another Material UI TypeScript component using React

In this scenario, we have two main components - the Drawer and the AppBar. The AppBar contains a menu button that is supposed to trigger an event opening the Drawer. However, implementing this functionality has proven challenging. I attempted to use the li ...

The value of type 'X' cannot be assigned to type 'Y' or 'undefined'

In my code, there is a component that requires a prop with an enum value: export enum AType { some = "SOME", word = "WORD", } const MyComponent = (arg: AType) => {} When I try calling this component like so: <MyComponent ar ...

I am unable to utilize the Web Share API for sharing a file within my React app written in TypeScript

Trying to launch a WebApp for sharing files has been quite a challenge. After some thorough research, I stumbled upon the Web Share API which seemed like the perfect solution based on standard practices. The documentation provided a clear outline of how it ...

What are the best strategies for effectively overseeing employees within nativescript?

Currently, I am immersed in a project that combines nativescript-vue and typescript, requiring me to interact with workers. Even though I've delved into the NS documentation and implemented the recommended approach for working with workers, I'm f ...

Tips for utilizing an elective conversion by typing

In my opinion, utilizing code is the most effective approach to articulate my intentions: interface Input { in: string } interface Output { out: string } function doStuff(input: Input): Output { return { out: input.in }; } function f<Out>(input ...

SystemJS TypeScript Project

I am embarking on a journey to initiate a new TypeScript project. My aim is to keep it simple and lightweight without unnecessary complexities, while ensuring the following: - Utilize npm - Implement TypeScript - Include import statements like: import ...