This happens because, once the code is transpiled, the child class property assignment happens after the parent constructor has been invoked, you can see that by using the typescript playground and set, in the options, to target ES5.
To make it shorter, the transpiled code will be the following:
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
var Entity = /** @class */ (function () {
function Entity(data) {
if (data) {
Object.assign(this, data);
}
}
return Entity;
}());
exports.Entity = Entity;
var Filter = /** @class */ (function (_super) {
__extends(Filter, _super);
function Filter(filter) {
var _this = _super.call(this, filter) || this;
_this.show = true;
return _this;
}
return Filter;
}(Entity));
exports.Filter = Filter;
new Filter({ show: false });
As you can see, the relevant part is that, in the Filter's contructor, the show property is assigned after the parent constructor has been executed.
var Filter = /** @class */ (function (_super) {
__extends(Filter, _super);
function Filter(filter) {
var _this = _super.call(this, filter) || this;
_this.show = true;
return _this;
}
return Filter;
}(Entity));
To solve the issue, you should just redesign your code and make sure you assign the property in the constructor, instead in the class declaration, leaving the class declaration empty:
export abstract class Entity {
constructor(data?) {
if (data) {
Object.assign(this, data);
}
}
}
export class Filter extends Entity{
public show: boolean;
constructor(filter?: Partial<Filter>) {
super(filter);
this.show = (this.show === undefined) ? true : this.show;
console.log(this);
}
}
new Filter({show:false}); // show is false
new Filter(); // show is true (default value)
Working code: https://stackblitz.com/edit/typescript-c4u557
Another possible approach is that Entity class should have a show property with a default value, but it doesn't seems like you want do that, from the hierarchy you've shown.