Nazar Hussain
Nazar Hussain

Reputation: 5162

Typescript: How to initialise a class property outside constructor

I have a scenario where I need to initialize a class property outside the constructor. Consider the following example.

class A {
    public prop: MyPropType;
    public id: string;

    public constructor(id: string) {
        this.id = id;
    }

    public init(value: string): void {
        this.prop = new MyPropType(value);
    }

    public toString(): string {
        return `${this.id} - ${this.prop.toString()}`;
    }
}

In above scenario I got error:

TS2564: Property ‘ prop’ has no initializer and is not definitely assigned in the constructor.

And if I make that property optional prop?: MyPropType then it starts complaining about its usage.

TS2532: Object is possibly 'undefined'.

Both errors are quite understandable. I am looking for the right way and approach in Typescript to come around such a scenario.

Should we use as at every usage e.g. (this.prop as MyPropType).toString(), or is there any other Typescript way?

And if we make assertions on the usage of the functions, why Typescript didn't recognize it?

    public toString(): string {
        assert(this.prop, 'Object property is not initialized');

        return `${this.id} - ${this.prop.toString()}`;
    }

Is there any way Typescript recognizes the above scenario and feels ok with it?

Upvotes: 6

Views: 3902

Answers (3)

Pinkierar
Pinkierar

Reputation: 1

There is also a way to initialize with undefined when declaring with casting it to any.

class Some {
  private value: string = undefined as any;

  public init(value: string) {
    this.value = value;
  }
}

Upvotes: 0

Nazar Hussain
Nazar Hussain

Reputation: 5162

I end up solving above problem with following pattern without changing any configuration related to typescript or tslint.

class A {
    private _prop?: MyPropType;
    public id: string;

    public constructor(id: string) {
        this.id = id;
    }

    public init(value: string): void {
        this._prop = new MyPropType(value);
    }

    public get prop() : MyPropType {
        return this._prop as MyPropType;
    }

    public toString(): string {
        return `${this.id} - ${this.prop.toString()}`;
    }
}

With this approach value of prop is initialized outside constructor and still can access the prop in the code without any warning or linting error.

Upvotes: 2

Murat Karagöz
Murat Karagöz

Reputation: 37584

You can turn off the "strictPropertyInitialization" in your tsconfig which states that all properties have to be initialized in the constructor or

use the Non-null assertion operator / bang operator e.g.

public prop!: MyPropType;

Upvotes: 4

Related Questions