Skip to content
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

this type should return instance type when overridden #2904

Open
mattjohnsonpint opened this issue Feb 3, 2025 · 2 comments · May be fixed by #2906
Open

this type should return instance type when overridden #2904

mattjohnsonpint opened this issue Feb 3, 2025 · 2 comments · May be fixed by #2906
Labels

Comments

@mattjohnsonpint
Copy link
Contributor

mattjohnsonpint commented Feb 3, 2025

Bug description

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

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

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
Copy link
Contributor Author

mattjohnsonpint commented Feb 3, 2025

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

@mattjohnsonpint
Copy link
Contributor Author

I think this gives a clue to the issue:

assemblyscript/src/resolver.ts

Lines 2859 to 2861 in 9a7a6e0

// Instance method prototypes are pre-bound to their concrete class as their parent
if (prototype.is(CommonFlags.Instance)) {
classInstance = assert(prototype.getBoundClassOrInterface());

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

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

@mattjohnsonpint mattjohnsonpint linked a pull request Feb 5, 2025 that will close this issue
2 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant