microsoft / TypeScript

TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
https://www.typescriptlang.org
Apache License 2.0
100.98k stars 12.48k forks source link

In an anonymous class, accessing `static` `class` property in instance method via `this.constructor` is reported as an error (is not an error) [Javascript, but TypeScript checking it] #60449

Open gima opened 2 hours ago

gima commented 2 hours ago

🔎 Search Terms

"class" AND "private" AND ("field" OR "property") AND ("must be declared in an enclosing class" OR "does not exist on type Function") AND "static" AND "this.constructor" AND "private" AND -label:Suggestion

Relevant bugs:

🕗 Version & Regression Information

⏯ Playground Link

https://www.typescriptlang.org/play/?filetype=js#code/MYewdgzgLgBA5gUygYQDYEMIRgXhgCgEpcA+AKBkpmAyxgHoAqGAQTHAE8BbEAV2xqZsjejADeFKlOjooAS2AwAxIKwAFAE5yAbrIS4YARgBMAZgDcZSVMoz5ixCloRNOvUXHWbUjUl4awGCgACzkIADoVZ1ddKARLb0oAXytE+CQ0IRi9AFUIOTA4AElIKHQwYAQAWSRgkAATDwk0nz8AoNCI0FKNXmAoEA1I1RctWPivKRSpq27oGGQAGRYAZRWDR0ysIksyOZBUBHDUEDh8GABycM3osfdiHBwLgBoF5bXrjNu3OI9CS32h2OpwIVxuWTucTyBWKpXKlRqIQaHkeLwIYAQAHc3qsVkRCJ8nBCfghoYUSjIKtVasjiP8yEA

💻 Code

const getClass = () =>
    class /* Anonymous class */ {
        static #classPrivate = 123;

        static getClassPrivate() {
            return this.#classPrivate;
        }

        getClassPrivateUsingInstanceMethod() {
            return this.constructor.#classPrivate;
        }
    }

const CLASS = getClass();

console.log( '.getClassPrivate() ==', CLASS.getClassPrivate() );
console.log ('.getClassPrivateUsingInstanceMethod() ==', (new CLASS()).getClassPrivateUsingInstanceMethod() );

Running the above code works. Logs:

[LOG]: ".getClassPrivate() ==",  123 
[LOG]: ".getClassPrivateUsingInstanceMethod() ==",  123 

🙁 Actual behavior

TypeScript checker says there are errors in the code.

Errors in code

    Property '#classPrivate' does not exist on type 'Function'.

🙂 Expected behavior

No errors from TypeScript checker.

Additional information about the issue

The problem goes away when adding // @ts-ignore above the erroring line.

Except

when using VSCode¹ locally, the ts-ignore directive does nothing. If I add // @ts-check at the top of the file, the ts-ignore directive works as expected.

¹ (built-in TypeScript version 5.6.3, Restricted Mode)

jcalz commented 1 hour ago

Isn't this a duplicate of #32452, which you linked above? How does this differ? I'd expect both class expressions and class declarations to have the same behavior with regards to the constructor property.