Description
The TypeScript specification currently reads:
The first statement in the body of a constructor must be a super call if both of the following are true:
- The containing class is a derived class.
- The constructor declares parameter properties or the containing class declares instance member variables with initializers.
It is reasonable in TypeScript to not permit this
to be referenced in a constructor before calling super
when there are initialized properties or constructor parameter properties because this
is not fully initialized until after super
is called. But broader restrictions on calling other code before super
that is not directly using this
don't seem that helpful and can be worked around anyway. So why keep them?
A common use case for having code before a call to super
is to transform constructor parameters in the subclass constructor before passing them to the superclass constructor. If such transformations are complex, a programmer might want to do the transformation step-by-step on multiple lines for increased readability and easier debugging.
An example of bypassing the compiler's restriction of no code before super
is just making function calls wrapping arguments to a super
call such as super(logThisName(name))
where the called function refers to this
.
As show by an example in the Handbook discussion linked below on improving the explanation for TypeScript constructor restrictions, ES6 permits other code in a constructor before a super
call (although accessing this
in called code would generate a runtime error before super was called). TypeScript is being more strict than what ES6 permits, and sometimes that is a good thing. But, is there any real value in this case by differing from what ES6 allows overall -- compared to just getting in the way? Why not always always allow code before a super
call when it does not use this
? Does the benefit of not allowing code before a super
sometimes really benefit anyone compared to the confusion caused by requiring programmers to use awkward workarounds and to learn a more complex rule for writing constructors than "Don't use this
before calling super
"?
This idea was originally brought up in issue #945 (closed in October 2014). I am creating a new issue for that as discussed with @mhegazy here: microsoft/TypeScript-Handbook#214. There is a code example in that Handbook issue which can be used for testing the current behavior for TypeScript, Babel, and ES6.