You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Extending a class method with prototype assignment confuses the compiler about membership type #22895
index.js:7:19 - error TS2424: Class 'Ex' defines instance member function 'foo', but extended class 'MyClass' defines it as instance member property.
7 MyClass.prototype.foo = function() {
~~~
Well, actually it turns out that it's the arrow function being used as a method. This is ... weird, but technically correct as long as the author remembers that this isn't an instance of Ex. I'll have a fix up shortly; I see a couple of ways to do it.
Note that --noImplicitThisworks with "checkJs": true, but it marks every usage of this outside a class, which makes it hard to use transitionally. So recognising arrow functions as methods is good for understanding existing code, but bad in that it doesn't prevent js authors from possibly buggy new code.
I think the right thing is to prefer understanding existing code, since we hope people with write new code in Typescript. They will, at least, have years of experience lowering their expectations of the correctness of any new Javascript that they write.
lib/NormalModule.js:455:2 - error TS2425: Class 'Module' defines instance member property 'size', but extended class 'NormalModule' defines it as instance member function.
455 size() {
~~~~
Yikes! OK, the problem this time is that the initialisers on the base aren't methods at all. They are null, which is definitely not method-like. I think the intention is to document that they are "abstract", but without creating a notImplementedFunction that always throws.
Upon re-reading the override checking code, it seems that the intent of the error is to prevent instance vs property confusion like this:
classSuper{constructor(){this.p=()=>1}}classSubextendsSuper{p(){return2}}console.log(newSub().p())// 1 ???!!!?classBase{getx(){return1}}classDerivedextendsBase{}Derived.prototype.x=2console.log(newDerived().x)// 1 ??/?? it keeps happening
So "isMethodLike" should really be "isPrototypeProperty" but the compiler is not very good at tracking this distinction. Fortunately, for Javascript special assignments, we can just look at the left-hand-side of the assignment. I'll go make that change.
Activity
sandersn commentedon Mar 27, 2018
Fix is up at #22935
mohsen1 commentedon Apr 1, 2018
Nathan Shively-Sanders (@sandersn) using the nightly I'm still getting the error
mohsen1/ts-bug-instance-member#1
sandersn commentedon Apr 2, 2018
I see, it looks like it breaks going the other direction, when the base uses prototype assignment. I’ll take anothe look.
sandersn commentedon Apr 2, 2018
Well, actually it turns out that it's the arrow function being used as a method. This is ... weird, but technically correct as long as the author remembers that
thisisn't an instance ofEx. I'll have a fix up shortly; I see a couple of ways to do it.sandersn commentedon Apr 2, 2018
Note that
--noImplicitThisworks with"checkJs": true, but it marks every usage ofthisoutside a class, which makes it hard to use transitionally. So recognising arrow functions as methods is good for understanding existing code, but bad in that it doesn't prevent js authors from possibly buggy new code.I think the right thing is to prefer understanding existing code, since we hope people with write new code in Typescript. They will, at least, have years of experience lowering their expectations of the correctness of any new Javascript that they write.
sandersn commentedon Apr 2, 2018
OK, the fix is merged. Mohsen Azimi (@mohsen1) can you try
typescript@nexttomorrow?mohsen1 commentedon Apr 2, 2018
Thank you for prompt response Nathan Shively-Sanders (@sandersn)!
mohsen1 commentedon Apr 4, 2018
Still seeing this error with latest TS nightly.
Run
yarn tscin this branch of Webpack to see errors:https://github.com/mohsen1/webpack/tree/bd1c827c884d943f68bbbf00cd91003875ae0bb2
sample:
sandersn commentedon Apr 4, 2018
Yikes! OK, the problem this time is that the initialisers on the base aren't methods at all. They are
null, which is definitely not method-like. I think the intention is to document that they are "abstract", but without creating anotImplementedFunctionthat always throws.Upon re-reading the override checking code, it seems that the intent of the error is to prevent instance vs property confusion like this:
So "isMethodLike" should really be "isPrototypeProperty" but the compiler is not very good at tracking this distinction. Fortunately, for Javascript special assignments, we can just look at the left-hand-side of the assignment. I'll go make that change.
sandersn commentedon Apr 4, 2018
OK, #23137 improves the
isMethodLikecheck.