admin管理员组

文章数量:1399805

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 plaining 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 e 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?

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 plaining 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 e 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?

Share Improve this question edited Jan 16, 2020 at 11:37 Deepak Singh 944 silver badges28 bronze badges asked Jan 16, 2020 at 11:04 Nazar HussainNazar Hussain 5,1726 gold badges43 silver badges67 bronze badges 4
  • What is the definition of MyPropType ? – Orelsanpls Commented Jan 16, 2020 at 11:11
  • Any custom class – Nazar Hussain Commented Jan 16, 2020 at 11:16
  • You can put ! after this.prop to tell typescript that this will always be defined if that's the case. – amanagg1204 Commented Jan 16, 2020 at 11:48
  • That's a really nice solution but stricter by TSLint TSLint: Forbidden non null assertion(no-non-null-assertion). The first answer to question describe how to get around it. – Nazar Hussain Commented Jan 16, 2020 at 12:05
Add a ment  | 

3 Answers 3

Reset to default 4

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;

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.

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;
  }
}

本文标签: javascriptTypescript How to initialise a class property outside constructorStack Overflow