Ensure the proper sequence of field initialization within a TypeScript class constructor

Is there a way to ensure the proper initialization order of class fields in TypeScript (4.0) constructors?

In this example (run), this.x is accessed in the method initY before it's initialized in the constructor:

class A  {
  readonly x: number
  readonly y: number

  constructor(x: number){
    this.y = this.initY() // this.x not initialized yet
    this.x = x
  }

  private initY(): number {
    return this.x + 1
  }
}

console.log(new A(1).y) // prints: NaN

The solution I found involved using a static method or top-level function for initialization.

Any other more concise ideas? Can the compiler (already in strict mode) or linter catch these issues?

Answer №1

To ensure type safety, one approach is to declare members as nullable types and implement typeguards to verify before using variables that can be null.

This method involves declaring x and y as a union of number | null

class A  {
  readonly x: number | null
  readonly y: number | null

  constructor(x: number){
    this.y = this.initY() // x is not initialized yet
    this.x = x
  }

  private initY(): number {
    // Will not compile unless you check for null first
    return this.x + 1
  }
}

https://i.stack.imgur.com/usDmy.png

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

Retrieve type definitions for function parameters from an immutable array containing multiple arrays

My current challenge involves implementing a function similar to Jest's test.each iterator: // with "as const" forEach([ [ 1, 2, 3 ], [ "a", "b", "c" ], ] as const, (first, second, third) => { // ...

Using command line arguments in a Tauri project with a Next.js frontend

I am utilizing Tauri.JS in conjunction with Next.js. In this scenario, I need to execute the console command: npm run tauri dev --<argument name>=<some value>. Afterwards, I should be able to access the value of the argument in my JavaScript ...

Error encountered when using withRouter together with withStyles in Typescript on ComponentName

Building an SPA using React with Typescript and Material UI for the UI framework. Stuck on a recurring error across multiple files - TS2345 Typescript error: Argument of type 'ComponentType<Pick<ComponentProps & StylesProps & RouteCompo ...

A peculiar quirk with Nuxt.js radio buttons: they appear clickable but are somehow not disabled

I’m having an issue with a radio button that won’t check. It seems to be working fine on other pages, but for some reason it just won't click here. <div class="form-group"> <label class="control-label&q ...

Another return payload failing to retrieve the return value

I'm currently facing an issue where a function that should return a value is not being passed on to another function. Below is the code snippet in question: public _getProfileToUpdate() { return { corporateId: this.storeService.setStoreData().p ...

Check out the uploaded file preview on React Native Expo!

I'm attempting to display a preview of the file uploaded by the user, which could be in pdf, img, or doc format. I tried a method that previews the file using a specific URL, but what I really want is for it to only show the preview of the uploaded fi ...

Attempting to create a universal logger factory using a functional approach

After reading Martin Fowler's blog on domain oriented observability, I was inspired to implement this concept without relying on classes. However, I encountered some challenges involving generics in TypeScript. Here is the snippet of my code (the erro ...

Injecting Dependencies with Angular 2 and the Ability to Include Optional Parameters

One issue I'm facing is that I have multiple components in my Angular 2 application that require the same dependency. This specific dependency needs a string for the constructor. How can I instruct angular2 to use a specific instance of this type for ...

Sending geographic coordinates from a child component in a React application using Google Maps to its parent component within a functional

My current project involves creating a map component in my React application using @googlemaps/react-wrapper. I followed the example from Google Maps and successfully added an event to refresh coordinates when dragging the marker. Now, I need to call the m ...

Setting up your Angular2-Typescript application to run smoothly in VS Code

I'm feeling quite lost here, could someone please help me make sense of this configuration? launch.json "configurations": [ { "name": "Launch", "type": "node", "request": "launch", "program": " ...

Why isn't my Promise fulfilling its purpose?

Having trouble with promises, I believe I grasp the concept but it's not functioning as expected in my project. Here is a snippet of my code : (I am working with TypeScript using Angular 2 and Ionic 2) ngOnInit() { Promise.resolve(this.loadStatut ...

WebStorm displays all imported items as unused in a TypeScript backend project

https://i.stack.imgur.com/J0yZw.png It appears that the image does not display correctly for files with a .ts extension. Additionally, in .tsx files, it still does not work. In other projects using WebStorm, everything works fine, but those projects are o ...

Is there a way to ensure that the observer.next(something) received the value before executing observer.complete()?

I have been working on an Angular app where I am using a resolver to preload data in the component. Below is the code for the resolver: resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): void { return Observable.create(observer => { ...

Sharing data between components in Angular 2 using the <router-outlet> technique

Having just started exploring Angular 2, I am eager to pass a boolean value from one component to another using <router-outlet> After some research, it seems like the best approach is to utilize a service. My aim is to toggle a boolean variable in ...

Oops! The program encountered an issue on the production environment, but it's running smoothly

When I execute Webpack using the command node node_modules/webpack/bin/webpack. js --env. prod An error message is displayed below. However, when running in --env. dev mode, the command executes without any issues. Can't resolve './../$$_gen ...

I'm diving into the world of Typescript and trying to figure out how to use tooltips for my d3 stacked bar chart. Any guidance on implementing mouseover effects in Typescript would be greatly

I am currently facing some issues with the code below and need guidance on how to proceed. I am new to this and unsure of how to call createtooltip. Any assistance would be greatly appreciated. The error message states that createtooltip is declared but n ...

Establishing a server in Node.js alongside an Angular 2 frontend by harnessing the power of Typescript

I'm looking to deploy my web application on IBM Bluemix with Angular 2 using Typescript for the frontend and Node.js for the backend. Can you advise me on how to configure the server, connect it to the frontend, and specify which transpiler I should u ...

Jest.useFakeTimers() causing clearTimeout test to malfunction

I've been exploring the transition to the newer version of jest.useFakeTimers(), which is not set as default in the latest 27.x release. Encountering some issues during my tests, Jest keeps flagging that functions like clearTimeout and setInterval a ...

Lazy loading in Angular allows you to navigate directly to a certain feature component

I'm currently working on implementing lazy loading in Angular 6, and I want to include links on my main homepage that direct users to specific feature components. Here is the hierarchy of my project: app.module.ts |__homepage.component.ts |__options ...

When renaming a Vuex module, the system mistakenly believes the old module is still present

After attempting to rename my modules, I encountered a perplexing error. Originally, I had a module named "speed" which I decided to change to "team". Despite updating all references accordingly, I am now facing the following error message: Error: Missing ...