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

static methods can access this.constructor without complaints and compiles correctly, but a runtime error shows up #58210

Closed
LeOndaz opened this issue Apr 16, 2024 · 13 comments
Labels
Question An issue which isn't directly actionable in code

Comments

@LeOndaz
Copy link

LeOndaz commented Apr 16, 2024

🔎 Search Terms

static, static method this, this static

🕗 Version & Regression Information

  • This is a crash (in runtime)
  • This changed between versions ______ and _______
  • This changed in commit or PR _______
  • This is the behavior in every version I tried, and I reviewed the FAQ for entries about _________
  • I was unable to test this on prior versions because it seems like a feature that's not implemented yet

⏯ Playground Link

https://stackblitz.com/edit/vitejs-vite-cwkeqq?file=src%2Fmain.ts

💻 Code

class MyClient {
  public static x: number = 20;
  public y: string;

  constructor () {
    this.y = "This is a demo"
  }

  static getInstance() {
    return this.constructor('THIS WON"T COMPILE CORRECTLY')
  }
}

🙁 Actual behavior

Typescript does not complain, but this does not compile correctly

🙂 Expected behavior

An error because I'm accessing this in a static method or compile correctly, or both

Additional information about the issue

This does happen with this.constructor but does not happen with this.y

In other words, accessing this.y shows an error.

@LeOndaz
Copy link
Author

LeOndaz commented Apr 16, 2024

TS versions tested and reproduce the same bug:

  • 5.2.2
  • 5.4.5

@MartinJohns
Copy link
Contributor

MartinJohns commented Apr 16, 2024

this in a static context is valid and refers to the static side of the class. The issue is that the constructor is typed as non-specific Function, which is a design limitation. There's an open issue #3841 for this. edit: This was not correct. See Andarist response.

@LeOndaz
Copy link
Author

LeOndaz commented Apr 16, 2024

@MartinJohns does this mean that it should work, but un-typed ?

@LeOndaz LeOndaz changed the title static methods can access this.constructor without complaints static methods can access this.constructor without complaints but a compilation shows up Apr 16, 2024
@LeOndaz
Copy link
Author

LeOndaz commented Apr 16, 2024

@MartinJohns I forgot some crucial details, I've updated this

This issue focuses on the failure of compilation, rather than the type error itself, I just revised where I faced this

@LeOndaz
Copy link
Author

LeOndaz commented Apr 16, 2024

Here's an example of the error:
image

@MartinJohns
Copy link
Contributor

on the failure of compilation

But it compiles fine, you just end up with a runtime error. This is to be expected, because your static constructor can not deal with the argument you provide. That TypeScript lets you provide that argument without a compilation error is due to the issue I mentioned before.

@LeOndaz
Copy link
Author

LeOndaz commented Apr 16, 2024

@MartinJohns not sure what I would call it, but isn't a Syntax error a sign that the output of TS is not correct? I understood what you sent, I'm just trying to know what's happening in runtime, it tries to run a bad javascript file, which means ts compiled it badly, because it didn't know how to handle this case right? this case in typescript's opinion, is fine, but once we get it running, it's not?

@LeOndaz LeOndaz changed the title static methods can access this.constructor without complaints but a compilation shows up static methods can access this.constructor without complaints and compiles correctly, but a runtime error shows up Apr 16, 2024
@Andarist
Copy link
Contributor

The syntax error reported here comes from JS - not TS. What @MartinJohns is saying is that this is valid and it works:

class MyClient {
  static x = 20;
  y;

  constructor() {
    this.y = "This is a demo";
  }

  static getInstance() {
    return this.constructor("return Math.random();");
  }
}

const x = new MyClient();

const mathRandom = MyClient.getInstance();

console.log(mathRandom(), mathRandom(), mathRandom());

The problem with your code is that you are essentially trying to compile a function with such body:

THIS WON"T COMPILE CORRECTLY

And this, in fact, won't compile correctly 😉

@LeOndaz
Copy link
Author

LeOndaz commented Apr 16, 2024

@Andarist forgive my lack of knowledge, how is it valid and works but at the same time the compilation results in this weird eval version, my brain is overheating now

@Andarist
Copy link
Contributor

Within the static block the this.constructor doesn't point to your MyClient.prototype.constructor but to Function (same as (class Foo {}).constructor). So the code above is equivalent to this:

class MyClient {
  static x = 20;
  y;

  constructor() {
    this.y = "This is a demo";
  }

  static getInstance() {
//    return this.constructor("return Math.random();"); // same thing as the one below
    return Function("return Math.random();");
  }
}

const x = new MyClient();

const mathRandom = MyClient.getInstance();

console.log(mathRandom(), mathRandom(), mathRandom());

@LeOndaz
Copy link
Author

LeOndaz commented Apr 16, 2024

@Andarist got it, when I read what @MartinJohns mentioned, I thought the return type is Function but it's value points to MyClient.prototype.constructor.

This is why I asked if it's untyped in my reply, all good now, thanks for taking the time to reply and thanks you @MartinJohns as well

@RyanCavanaugh RyanCavanaugh added the Question An issue which isn't directly actionable in code label Apr 17, 2024
@RyanCavanaugh
Copy link
Member

TypeScript doesn't validate code that is, for all intents and purposes, inside an eval call

@typescript-bot
Copy link
Collaborator

This issue has been marked as "Question" and has seen no recent activity. It has been automatically closed for house-keeping purposes.

@typescript-bot typescript-bot closed this as not planned Won't fix, can't repro, duplicate, stale Apr 20, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Question An issue which isn't directly actionable in code
Projects
None yet
Development

No branches or pull requests

5 participants