-
Notifications
You must be signed in to change notification settings - Fork 12.6k
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
Give a more helpful error message for certain decorators with too many arguments #18811
Conversation
…ressions that take no arguments.
1f1f1be
to
25e9e06
Compare
25e9e06
to
08ef6e4
Compare
@@ -1,4 +1,4 @@ | |||
tests/cases/conformance/decorators/class/method/decoratorOnClassMethod6.ts(4,5): error TS1241: Unable to resolve signature of method decorator when called as an expression. | |||
tests/cases/conformance/decorators/class/method/decoratorOnClassMethod6.ts(4,5): error TS1329: This value has type '() => <T>(target: any, propertyKey: string, descriptor: TypedPropertyDescriptor<T>) => TypedPropertyDescriptor<T>' which accepts too few arguments to be used as a decorator here. Did you mean to call it first? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would be nicer if you had the decorator name in the error message, e.g.:
Did you mean '@dec()' instead?
* In those cases, a user may have meant to *call* the expression before using it as a decorator. | ||
*/ | ||
function isPotentiallyUncalledDecorator(decorator: Decorator, signatures: Signature[]) { | ||
return signatures.length && every(signatures, signature => |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should you also check that the return type is callable/any
to ensure your suggestion of calling it is warranted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
any
is accounted for - it's an uncalled function call. It also has no signatures.
This should be marked as breaking change. the recommendation is to add rest args in the signature. |
src/compiler/checker.ts
Outdated
@@ -16381,6 +16381,11 @@ namespace ts { | |||
return resolveUntypedCall(node); | |||
} | |||
|
|||
if (isPotentiallyUncalledDecorator(node, callSignatures)) { | |||
error(node, Diagnostics.This_value_has_type_0_which_accepts_too_few_arguments_to_be_used_as_a_decorator_here_Did_you_mean_to_call_it_first, typeToString(funcType)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The type here seems weird. it might be long, and hides the main message. why not just say '${0}' expects too few arguments to be called as a decorator, did you mean
@${0}()' instead?`
I think this should get the majority of the cases, for other ones we will fallback to unable to resolve decorator when called as a function
message.
5450bc7
to
7750a88
Compare
Why? These decorators could never have succeeded as they would receive too many arguments. |
Right now this only works for single-signature decorators that accept no arguments. We could improve this to cases wherethere are too many arguments from the decorated entity for every signature andthe min arg count is 0 for every signatureWe now give a more helpful error message when
This comes up for me all the time in Angular where I end up forgetting to invoke the decorator: