Skip to content

Add JS-specific diagnostic message for resolve() in Promise where type argument can't be inferred #48533

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

Merged
merged 3 commits into from
Apr 27, 2022

Conversation

nicdard
Copy link
Contributor

@nicdard nicdard commented Apr 3, 2022

Fixes: #46570

Continues #46637
I have cherry picked the commit from there.
Address the comments of the above PR, restricting the change to JS files.

@typescript-bot typescript-bot added the For Backlog Bug PRs that fix a backlog bug label Apr 3, 2022
@nicdard nicdard marked this pull request as draft April 3, 2022 10:57
@nicdard nicdard marked this pull request as ready for review April 3, 2022 11:07
@nicdard nicdard marked this pull request as draft April 3, 2022 11:19
@nicdard nicdard force-pushed the fix/46570 branch 5 times, most recently from 403227f to d89aac4 Compare April 3, 2022 13:32
@nicdard nicdard marked this pull request as ready for review April 3, 2022 13:56
@@ -3365,6 +3365,10 @@
"category": "Error",
"code": 2809
},
"Expected {0} arguments, but got {1}. TypeScript may need a JSDoc hint that the call to 'new Promise()' produces a 'Promise<void>'": {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe this was the message suggested in the issue, so it make sense to use it, but this wording strikes me as off as I'm not sure that we have any error messages that effectively "blame" TypeScript itself for needing a hint about the code's behavior, at least not in this particular wording. I would have written something more like

This promise may need a JSDoc-style type that the call to 'new Promise()' produces a 'Promise'

To shift things around to pointing at the particular code that's at fault, not at the language itself.

But, this is bikeshedding. @DanielRosenwasser @andrewbranch

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I agree this message doesn’t quite fit. What exactly does the codefix for JS do? Does it add an annotation both for variable declarations and expressions (i.e. a type assertion)?

Copy link
Contributor Author

@nicdard nicdard Apr 26, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It adds a type tag:

var a = /** @type {Promise<void>} */(new Promise(resolve => resolve()));

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about

'new Promise()' needs a JSDoc hint to produce a 'resolve' that can be called without arguments.
  • 'resolve' could be substituted with an interpolation to use the parameter name the user wrote.
  • The first interpolation ({0} arguments) is unnecessary as we know it’s 0.

(cc @DanielRosenwasser)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, this provides better feedback indeed :)

@andrewbranch andrewbranch changed the title Fix/46570 Add JS-specific diagnostic message for resolve() in Promise where type argument can't be inferred Apr 26, 2022
@@ -3365,6 +3365,10 @@
"category": "Error",
"code": 2809
},
"Expected {0} arguments, but got {1}. TypeScript may need a JSDoc hint that the call to 'new Promise()' produces a 'Promise<void>'": {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I agree this message doesn’t quite fit. What exactly does the codefix for JS do? Does it add an annotation both for variable declarations and expressions (i.e. a type assertion)?

@nicdard nicdard force-pushed the fix/46570 branch 2 times, most recently from 49d95c5 to 94dc46b Compare April 26, 2022 18:32
@andrewbranch
Copy link
Member

In a separate PR, we should consider expanding the codefix to cover

/** @param {() => void} resolve */
function alwaysResolve(resolve) { resolve() }
new Promise(alwaysResolve);

(both JS and TS versions)

@nicdard
Copy link
Contributor Author

nicdard commented Apr 26, 2022

In a separate PR, we should consider expanding the codefix to cover

/** @param {() => void} resolve */
function alwaysResolve(resolve) { resolve() }
new Promise(alwaysResolve);

(both JS and TS versions)

I see, it is complaining indeed now but no code fix is provided, I would be happy to help with this and open another PR later :)

@andrewbranch
Copy link
Member

Yes. It’s a different error but the same fix can be applied.

@nicdard nicdard force-pushed the fix/46570 branch 3 times, most recently from f300244 to 8a66d15 Compare April 27, 2022 06:47
: Diagnostics.Expected_0_arguments_but_got_1;
const isVoidPromiseError = !hasRestParameter && parameterRange === 1 && args.length === 0 && isPromiseResolveArityError(node);
if (isVoidPromiseError && isInJSFile(node)) {
return getDiagnosticForCallNode(node, Diagnostics.Expected_1_argument_but_got_0_new_Promise_need_a_JSDoc_hint_to_produce_a_0_that_can_be_called_without_arguments, "resolve");
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any convenient way to get the name of the function? I tried symbolName(node.symbol) without success

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

resolveName(node.expression, node.expression.escapedText, SymbolFlags.Value, undefined, undefined, false)?.name

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It may also be reasonable just to call it resolve since that’s the parameter name in the library file.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I will change it to a straightforward string

@@ -3369,6 +3369,10 @@
"category": "Error",
"code": 2809
},
"Expected 1 argument, but got 0. 'new Promise()' need a JSDoc hint to produce a {0} that can be called without arguments.": {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"Expected 1 argument, but got 0. 'new Promise()' need a JSDoc hint to produce a {0} that can be called without arguments.": {
"Expected 1 argument, but got 0. 'new Promise()' needs a JSDoc hint to produce a {0} that can be called without arguments.": {

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh sorry for this!

Copy link
Member

@andrewbranch andrewbranch left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you!

@andrewbranch andrewbranch merged commit d45012c into microsoft:main Apr 27, 2022
@nicdard nicdard deleted the fix/46570 branch April 27, 2022 19:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
For Backlog Bug PRs that fix a backlog bug
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

Unhelpful "Did you forget to include 'void' in your type argument to 'Promise'" in JS file
5 participants