Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Inherited Constructors execute before sub class field initializations #13525

Closed
arciisine opened this issue Jan 16, 2017 · 5 comments
Closed
Labels
Question An issue which isn't directly actionable in code

Comments

@arciisine
Copy link

TypeScript Version: 2.1.5

Code

class Base {
  id:string;

  constructor(config:any) { 
      // Given a defined schema object, bind the inbound config to the current 
      //   instance, enforcing types and discarding unused fields
      bindToSchema(ObjectSchemaRegistry.get(this.constructor), this, config);
  }
}

class SubType extends Base {
   name:string = 'basic';
}

Expected behavior:
new SubType({ name : 'test' }).name == 'test'

Actual behavior:
new SubType({ name : 'test' }).name == 'basic'

The sub class field initialization executes after the base class constructor executes. I'm not sure if this is 100% desirable but I can understand the reasoning for it. If this is unchangeable, I would look for some way to execute the bindToSchema function after the sub class field initialization has occurred (barring making every use of the constructors call bindToSchema manually).

@vladima
Copy link
Contributor

vladima commented Jan 17, 2017

duplicate of #10634?

@arciisine
Copy link
Author

Sounds like it, didn't come up in my search. Is there any way to achieve this functionality (calling code after the constructors finish) without changing the order of construction?

@RyanCavanaugh RyanCavanaugh added the Question An issue which isn't directly actionable in code label Jan 17, 2017
@RyanCavanaugh
Copy link
Member

Nope. General pattern here is to have some convention like calling this.init() after super in the derived class constructors.

@arciisine
Copy link
Author

arciisine commented Jan 17, 2017

Understood, it just seems like an anti-pattern to have, what is essentially, a secondary constructor to compensate for the initialization of fields.

I'm toying with using an inherited static method to act as the constructor (e.g. Sub.new, or Sub.from), but I'm not sure if relying on inheritance for static members is a good idea either.

@arciisine
Copy link
Author

So, playing around with some solutions, what I'm looking at is:

class BaseSchema {
  static new<T>(this: new () => T, data: any): T {
    return BindUtil.bindSchema(this, new this(), data);
  }
}

This then allows for

class Person extends BaseSchema {
  name: string = 'bob';
}

let person:Person = Person.new({});

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Question An issue which isn't directly actionable in code
Projects
None yet
Development

No branches or pull requests

4 participants