TypeScript icon indicating copy to clipboard operation
TypeScript copied to clipboard

Well-typed ECMAScript decorators don't handle generic types in Args

Open cheit-epic opened this issue 2 years ago • 0 comments

Bug Report

Using the example loggedMethod in the release notes. with generic types that are used in args fails with the error

Types of parameters 'args' and 'args' are incompatible.
    Type 'unknown' is not assignable to type .

🔎 Search Terms

decorator, generic, unknown

🕗 Version & Regression Information

  • I was unable to test this on prior versions because these decorators are only available starting in 5.0+

⏯ Playground Link

Playground link with relevant code

💻 Code

function loggedMethod<This, Args extends any[], Return>(
    target: (this: This, ...args: Args) => Return,
    context: ClassMethodDecoratorContext<This, (this: This, ...args: Args) => Return>
) {
    const methodName = String(context.name);
    function replacementMethod(this: This, ...args: Args): Return {
        console.log(`LOG: Entering method '${methodName}'.`)
        const result = target.call(this, ...args);
        console.log(`LOG: Exiting method '${methodName}'.`)
        return result;
    }
    return replacementMethod;
}

class Foo
{
    @loggedMethod //fails
    logThis<T>(callback: (args: T) => void): void {}
}

🙁 Actual behavior

Compile error. I don't see why it needs to go deeper than the basic Args to be able to match the signature.

🙂 Expected behavior

No compile error, since this seems properly constrained to me. If not, how to properly type this to work on any method without resorting to ClassMethodDecoratorContext<This, any>?

cheit-epic avatar May 03 '23 22:05 cheit-epic