Two things are worrying me about TypeScript constructors that seems to make them incompatible with ES6.
The current ES6 says: If a constructor function needs to perform superclass initialization, it must do so by explicitly calling super(/arguments
/) at some point within the constructor body. -
Calling super is currently required
The proposal is not very clear about this leaving some room for interpretation, but it seems to make calling 'super()' optional, and up to the child class to decide if it needs to perform super class initialization or not. I would be really surprised if browsers
enforced that. This is not a big issue, but makes mandatory to execute code that would not be required to do so, creating possible performance issues for TypeScript code. Some libraries currently allow you to override the constructors at the runtime, and not
call the existing constructor at all (http://backbonejs.org/#Model-constructor
Calling 'super()' is required as the first statement of the constructor
This is a big issue. The proposal is very clear on this, where if
super initialization is required, it must be done
at some point
of the child constructor, not at the beginning.
This is a real issue, because libraries out there use this feature of the language and will continue using them because it creates a nice pattern. You can optionally define properties that will be used by the constructor, and then call the constructor without
worring about lots of optional arguments and their positions.
This "feature" makes TypeScript classes incompatible with existing libraries, and require workarounds to make them work correctly, like running initialization code twice.
I have been working with C# for the last 10 years, and have coded in other OO languages as well, and I understand why it would be good to have this added to the language. I don't want to discuss if this works in other platforms, because I know they work there
and provide required safeties to the code. Also, I'm not saying Backbone or other common JS libraries have exemplary architecture designs.
The point here is that these checks are enforcing the runtime to execute code that shouldn't run or that should run in a different order, and there is no way to prevent that.
Some ideas to solve this:
- TypeScript could enforce this based on a compiler option if the project requires the check, just like "noImplicitAny"
- TypeScript should not enforce this by default, but show warnings if you forget to call super or call it somewhere else
- TypeScript could not enforce these checks based on compiler option