-
Notifications
You must be signed in to change notification settings - Fork 12.5k
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
Support to method decorator that change the method signature #49229
Comments
It is usually an anti-pattern as decorators are meant to be transparent - meaning that no changes to method signature must be done by the decorator and only a behavior may be added/changed (like doing validation/logging). As for your case it seems like you are adding some extra "private" arguments that your consumer and receiver must not see/access and only your decorator can see and possibly some privileged part of the code? In this case you can create a shortcut mapped type that adds new argument on the fly so you can cast your method in place just before invoking it. Pseudo TS could look something like this: type AnyFunction = (...args: any[]) => any;
type ExtendedMethod<TMethod extends AnyFunction> = (
// Add extra argument of type "string" at the end
...args: [...Parameters<TMethod>, string]
) => any;
type ExtendedObject<T> = {
// Extend all methods on the object
[P in keyof T]: T[P] extends AnyFunction ? ExtendedMethod<T[P]> : T[P];
};
function asExtended<T>(obj: T) {
return obj as ExtendedObject<T>;
}
class Example {
method(a: number, b: number) {}
}
// Standard call
new Example().method(1, 2);
// Extended call that knows about extra argument
asExtended(new Example()).method(1, 2, '3'); |
I don't agree that decorators should only be used for validation/logging. I think that adding methods and properties to classes via decorators is one of their main goals and capabilities and typescript should be able to access to the added signatures. If there is such wish to let decorators remain a 'hidden' thing, maybe the best option would be to have a flag in compiler options like "DecoratorsChangeTypes" ? |
This feature would be a big QOL improvement for TS developers wanting to rely on composition over inheritance in their classes. It would be very natural to allow the wrapper method to have its own signature which, to me, would substantially increase the utility of existing decorator functionality. |
I hope it's going to be implemented right after decorators reach stage 4. Currently it doesn't make a lot of sense to be able to change signatures while decorators aren't standardised, unfortunately. |
To add onto the validation topic, I believe that is actually a very convenient case for changing the signature. When working with a library like Zod, it is not rare for the result of the parsing operation to have a different type than the input, even if it's just removing In my case, I wanted to write a decorator to do exactly that, i.e., running a method's input through a provided Zod schema first before calling the method itself, and then passing the result to the method. Since this is a use case that happens in many different places in the code, I thought that a decorator would be a great abstraction to avoid having to replicate the manual parse invocation at all usage sites. |
Suggestion
As the title said, I just started using typescript and I want to have a
method
decorator that is able to change the method signature and havetsc
knew about the new signature.🔍 Search Terms
I have seen a lot of works around
class
decorators, like #4881 but nothing specifically on supporting the behavior I have described.✅ Viability Checklist
My suggestion meets these guidelines:
⭐ Suggestion
If not for other things, I would like to understand if there is some way to set the types of
decorator
to signal the new decorated function signature.📃 Motivating Example
As a minimal example, look at
tsc
sasys that there is an error in the last line, because it doesn't "know" thatC.method
have a new signature, after applying thedecorator
.💻 Use Cases
I'm implementing a simple method wrapper that add a parameter to do pre-checks on method invocation itself
The text was updated successfully, but these errors were encountered: