-
Notifications
You must be signed in to change notification settings - Fork 12.6k
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
Arrow functions of a class show up on prototype #20922
Comments
What you describing is expected behaviour for any initialised public property of a class (not just arrow functions). Whether As far as I know, this is due to a deep language-design decision that revolves around an expectation that initialised class properties be owned by the instance, whereas class methods fall through to the prototype. Traditionally, when rolling your own JS-style classes, you could choose between setting a default value of a property the long-hand way that TS compiles to, or by setting the prototype directly: eg
If you do it this way, then the property is immediately available on the prototype, rather than having to wait for instantiation, but this leads to an inconsistency with properties that are later set (eg You can see the effect on your own code as follows:
When you roll your own code, then that design decision is yours, but I believe that this decision was made to also accommodate some constraints placed upon the system by the way that Perhaps a language developer can clarify this. |
@poseidonCore Yep you are right, I didn't realize that it is that way for any initialized property of a class. I'm just not sure if there is a reason why those properties would show up on the classes prototype when using Typescript. It seems to me like this shouldn't happen, but maybe a language dev can comment more on that. |
The In theory we could synthesize the "correct" type but it doesn't seem to matter in practice, and might break other stuff since this has been the behavior since first release. Did this behavior manifest as a bug in your code, or did you just happen to notice it? |
@RyanCavanaugh that makes sense. It's just confusing when using type hinting and things comes up when they aren't actually present on I happened to notice this when I was attempting to use jest to mock an arrow function on a class: Test.prototype.testArrowMethod = jest.fn().... I was also having issues trying to spy on that function, which ended up being the exact same issue ( So the solution for me was just to make it a non arrow-function. |
Also, bear in mind that TS (unlike some other languages) allows initialisation to non-primitive values: eg
and by initialising this in the constructor (rather than the prototype) means that these non-primitive objects are not shared between instances, and so
Compare that to standard TS:
This relates to the importance of instances owning their own properties in this regard and applies a standard approach. If the initialisation behaviour was changed to put the initial value in the prototype, this would affect any code that did things as noted here. |
This would be a big breaking change with very little upside in terms of actually catching bugs you would plausibly write. |
TypeScript Version: 2.7.0-dev.20171226
Code
Expected behavior:
Test.prototype.testArrowMethod
should fail on compilation because it isn't on the classes prototype.Actual behavior:
Test.prototype.testArrowMethod
does not fail on compilation but becomesundefined
at runtime.Reason
The code above compiles into the following js:
As can be seen, the arrow function is actually defined using
this
instead ofprototype
on instantiation. This is fine, buttestArrowMethod
should not be able to be accessed fromTest.prototype
The text was updated successfully, but these errors were encountered: