assemblyscript icon indicating copy to clipboard operation
assemblyscript copied to clipboard

`this` type should return instance type when overridden

Open mattjohnsonpint opened this issue 10 months ago • 2 comments

Bug description

Found via StackOverflow: https://stackoverflow.com/q/79232050/634824

TypeScript allows the this keyword to be used as a type.

  • https://www.typescriptlang.org/docs/handbook/2/classes.html#this-types
  • https://www.typescriptlang.org/docs/handbook/advanced-types.html#polymorphic-this-types

AssemblyScript seems to recognize this syntax and compiles fine:

class X {
  doSomething(): this {
      return this;
  }
}

However, in AssemblyScript, it always is treated as the class where this is used - which is not necessarily the type of the instance when the object is extended.

class Y extends X {
  doSomethingElse(): string {
      return "You made it!";
  }
}

Steps to reproduce

With the above code,

console.log(new Y().doSomething().doSomethingElse());

fails to compile. The error is:

ERROR TS2339: Property 'doSomethingElse' does not exist on type 'assembly/index/X'.
    :
 12 │ console.log(new Y().doSomething().doSomethingElse());
    │                                   ~~~~~~~~~~~~~~~
    └─ in assembly/index.ts(12,35)

Essentially, y.doSomething() is returning a type X where it should return a type Y.

TypeScript tooling believes the value should be Y, but AssemblyScript thinks it's X.

Image

Casting the value using <Y> or as Y works, but the point is that one may have full awareness of the original type when making the call.

AssemblyScript version

v0.27.32

mattjohnsonpint avatar Feb 03 '25 22:02 mattjohnsonpint

I think perhaps this may have been overlooked when implementing #1208 for #693.

mattjohnsonpint avatar Feb 03 '25 22:02 mattjohnsonpint

I think this gives a clue to the issue:

https://github.com/AssemblyScript/assemblyscript/blob/9a7a6e03679c12be24c55f9f05d3090e9042abb3/src/resolver.ts#L2859-L2861

The function prototype is X.doSomething, so the classInstance is X (not Y).

I think I will try to fix this. PR forthcoming...

mattjohnsonpint avatar Feb 05 '25 20:02 mattjohnsonpint