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

TSC/Intellisense - Cannot use Static method as argument for Decorated method on same class #60057

Closed
purebordem opened this issue Sep 25, 2024 · 2 comments
Assignees
Labels
Working as Intended The behavior described is the intended behavior; this is not a bug

Comments

@purebordem
Copy link

πŸ”Ž Search Terms

static, decorator, method, declaration

πŸ•— Version & Regression Information

  • This changed between versions - 5.4.5 and 5.5.4

⏯ Playground Link

https://www.typescriptlang.org/play/?target=9&ts=5.6.2#code/PTAEEkDNQVwZwJYDsDmoAqBlAwgeyZAmugIYBOKApgC6gCimATAAyMCMouZoANrgO6UyAGk4xqAB3GgEcAHQKAUCFABtOgCUNAXQBcoAER0AHpQDG4ygBNQAKRIA3EpjNkEE2gDESCHtd0GoMpg6lp6oGYkSADktCRmZpRwcLyUxgiRPKBW5jzkJNQI+KDRJiQAthJ+0aAARpSQXJQySAiFJDwIAF4FRUhBwRDQ8MjEOPiExORUtAwsjIyc3AAWRMtComa4OaBkMEgpcDAJSXCQMDw8AJ4KcoOqADIA8gDi4QYAsjTL26DTMOVKEhqIdjolkudLldQE5OlYCtZAvdnm99AYABKUS64UAAdS4PCsSMG4H6tVw1GWoEQ1BgvXwcFEyGoWM6cCB7OpP34KSEZC4g2weWSJTKlWqsHZNnqjTIzTaKRyZjyZHpSDuii2B1wfjkyso5AAFABKRSKahXCTNABqHQQ8OoXFAAF5QIbpnB9FErqptMaXQA+Oq4HUGpBm85IMyFYq2uEIw3IKTUfRx+0FLj+gDeilAed2NBgZH6kejfTd1GmNH0nn2Zfwm3wLOMKdAQpIyS+lO2ABFzFwM2Q8MC0tRjTn85OZJBDVrm9Q5ABrZA2Z2u6KA7tWaLj3NT-dy2nF0ClmP9Q2U2RepBXUS3D3Xn1+rP71+vvdv-cgWHpx3cfgdqAEj8g49rWB+n6TggM5JuIu6QZB352g6ToSB27JwBBCFTtBiZIMm7oUHAxrwdhCFanAoZyHwKCGtEXY-DY-yAsCoInBCFzXDCyEItuppkQhh5Fv0lYUDQcgkBIVRXBeqyMn8RH8QJU4AL5YcpWKchOylvhRVE0XRDG-MxQIggpzRIBSERcHK0YAIQ7upAlqTpLkaTwnKUvy-D0GQ-JkHRAByOI-ih3DAbgoE5FYDlKZBbn7ipoCac0XkCL5-l0X2Wyqn+oDlCQ0L4Fx9SStYnD9JujFwLFEFqWpmrCikYpVM02l5gAAmmDqUIaLW6uAcCYti+JkIScWgA8uC0bBrZwNQbioKR+56bqBmzRNDWTvNvRmBAQ2srgo2EnhyaPr6xr6OSoZRKA7U4TB+HiKozDaC667DXweIEnxBZHiJeyUE5yUec0QnHpAHTsnVigNRRtAfFc-XNK6SCUD5yMmmaiPI3IU20dEn04sdfFAA

πŸ’» Code

type Validator = (args: any[]) => boolean

function Validate(input: Validator) {
    return function (target: Function, context: ClassMethodDecoratorContext){
        if(context.kind == 'method'){
            return function (this: any, ...args: any[]){                    
                //validator was provided
                if(input){
                    //validator passes
                    if(input(args)){
                        console.log('Method arguments successfully validated')
                        return target.apply(this, args)
                    }
                    else {
                        console.log('Method arguments are not correct!')
                    }
                }
                else throw Error('No validator provided!')
            }
        } else throw Error('Decorator may only be used on methods!')
    }
}

class Example {
    @Validate(Example.IsHelloWorld) //intellisense - Class 'Example' used before its declaration.
    Log(input: string){
        console.log(input)
    }

    static IsHelloWorld(input: any[]): boolean {
        if(input[0] == 'Hello World') return true
        else return false
    }
}

const MyExample = new Example()

MyExample.Log('Hello World')

πŸ™ Actual behavior

When running TS 5.5.4 or higher...

If using TSConfig Target ES2021 or lower, output is...

// [ERR]: "Executed JavaScript Failed:" 
// [ERR]: can't access lexical declaration 'Example' before initialization

If using TSConfig Target ES2022 or higher, code runs successfully...

// [LOG]: "Method arguments successfully validated" 
// [LOG]: "Hello World" 

In both situations, intellisense shows error

// Class 'Example' used before its declaration.

πŸ™‚ Expected behavior

If the code generated can run successfully, I would expect TSC to not report an error and compile successfully. Currently need to leverage //@ts-ignore to compile

Additional information about the issue

No response

@RyanCavanaugh RyanCavanaugh added the Needs Investigation This issue needs a team member to investigate its status. label Oct 16, 2024
@rbuckton rbuckton added Working as Intended The behavior described is the intended behavior; this is not a bug and removed Needs Investigation This issue needs a team member to investigate its status. labels Oct 16, 2024
@rbuckton
Copy link
Member

This is the expected behavior. The fact Example is available is a side-effect of our downleveling and does not represent the actual runtime semantics of native ECMAScript Decorators. Per the specification text, decorators are evaluated in steps 27-37, but the binding for the class name is not initialized until step 38. If we were to allow this, then eventually switching to a --target with actual native decorator support would break.

@rbuckton
Copy link
Member

rbuckton commented Oct 16, 2024

I would suggest instead that you use @Validate(x => Example.IsHelloWorld(x)) to close over Example instead of taking a direct reference.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Working as Intended The behavior described is the intended behavior; this is not a bug
Projects
None yet
Development

No branches or pull requests

3 participants