AK_
AK_

Reputation: 8099

Typescript class with public properties results in an empty JavaScript object

I've created the following class:

  class TestInput {
        public a: boolean;
        public b: boolean;
        public c: boolean;

    }

later in the program I try to use it in the following way:

    let template = new TestInput();

    for (const key in template) {
        if (template.hasOwnProperty(key)) {
            template[key] = false;
        }
    }

Which does nothing, and causes an error later. while debugging in chrome template appears to be empty.

Looking at the generated JavaScript I see that TestInput is defined in the following way (which is kind of empty):

    var TestInput = /** @class */ (function () {
        function TestInput() {
        }
        return TestInput;
    }());

What am I doing wrong? Thanks!

Upvotes: 2

Views: 1000

Answers (2)

Titian Cernicova-Dragomir
Titian Cernicova-Dragomir

Reputation: 249756

This is the expected behavior. Class field declarations don't actually do anything to the emitted Javascript. They are there just for type checking.

If you add initializers to the field then the object will have the expected fields.

class TestInput {
    public a: boolean = false;
    public b: boolean = false;
    public c: boolean = false;

}

There is also an option strictPropertyInitialization to check that all properties are initialized (but it requires strictNullChecks)

Ensure non-undefined class properties are initialized in the constructor. This option requires --strictNullChecks be enabled in order to take effect.

Upvotes: 2

T.J. Crowder
T.J. Crowder

Reputation: 1074545

Even though the properties are declared, nothing ever actually creates them. A public property is only created if a value is assigned to it.

If you want to ensure they're always created, include an initializer on the declaration:

class TestInput {
    public a: boolean = false;
    public b: boolean = false;
    public c: boolean = false;
}

or assign to them in the constructor, etc.

That's true for TypeScript's public properties, but not for JavaScript's own public field declarations (now shipping without any flag in Chrome's V8). The declaration creates the property:

class TestInput {
    a;
    b;
    c;
}
const t = new TestInput();
console.log("a" in t); // true

Upvotes: 3

Related Questions