-
-
Notifications
You must be signed in to change notification settings - Fork 2.8k
feat(eslint-plugin): [prefer-promise-reject-errors] add rule #8011
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
feat(eslint-plugin): [prefer-promise-reject-errors] add rule #8011
Conversation
Thanks for the PR, @auvred! typescript-eslint is a 100% community driven project, and we are incredibly grateful that you are contributing to that community. The core maintainers work on this in their personal time, so please understand that it may not be possible for them to review your work immediately. Thanks again! 🙏 Please, if you or your company is finding typescript-eslint valuable, help us sustain the project by sponsoring it transparently on https://opencollective.com/typescript-eslint. |
✅ Deploy Preview for typescript-eslint ready!
To edit notification comments on pull requests, go to your Netlify site configuration. |
packages/eslint-plugin/docs/rules/prefer-promise-reject-errors.md
Outdated
Show resolved
Hide resolved
packages/eslint-plugin/tests/rules/prefer-promise-reject-errors.test.ts
Outdated
Show resolved
Hide resolved
packages/eslint-plugin/tests/rules/prefer-promise-reject-errors.test.ts
Outdated
Show resolved
Hide resolved
packages/eslint-plugin/tests/rules/prefer-promise-reject-errors.test.ts
Outdated
Show resolved
Hide resolved
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.
Awesome, really solid work here - thanks for working on it @auvred!
It's interesting that this is the first rule to really need to check whether something is actually a 'PromiseConstructor'
. Others have just approximated comparisons to Thenable
.
A few touchups & refactors requested, but the general direction looks great to me! 🚀
packages/eslint-plugin/docs/rules/prefer-promise-reject-errors.md
Outdated
Show resolved
Hide resolved
function isPromiseConstructorLike(type: ts.Type): boolean { | ||
const symbol = type.getSymbol(); | ||
|
||
if (symbol?.getName() === 'PromiseConstructor') { | ||
const declarations = symbol.getDeclarations() ?? []; | ||
for (const declaration of declarations) { | ||
const sourceFile = declaration.getSourceFile(); | ||
if (program.isSourceFileDefaultLibrary(sourceFile)) { | ||
return true; | ||
} | ||
} | ||
} | ||
|
||
return false; | ||
} |
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.
[Refactor] This is roughly the same logic as isErrorLike
's for checking if it's a built-in of a particular name. Could you extract into a shared helper for this too?
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.
Not sure about the function name, but I extracted it: https://github.com/typescript-eslint/typescript-eslint/pull/8011/files#diff-75626015398ba4cc6293d6ec23077170a50f23e306b326a44966e44448c3edf2
TODO: refactor these places to use this function
typescript-eslint/packages/eslint-plugin/src/rules/no-implied-eval.ts
Lines 82 to 90 in 705370a
if (symbol && symbol.escapedName === FUNCTION_CONSTRUCTOR) { | |
const declarations = symbol.getDeclarations() ?? []; | |
for (const declaration of declarations) { | |
const sourceFile = declaration.getSourceFile(); | |
if (services.program.isSourceFileDefaultLibrary(sourceFile)) { | |
return true; | |
} | |
} | |
} |
typescript-eslint/packages/eslint-plugin/src/rules/no-implied-eval.ts
Lines 145 to 153 in 705370a
if (symbol) { | |
const declarations = symbol.getDeclarations() ?? []; | |
for (const declaration of declarations) { | |
const sourceFile = declaration.getSourceFile(); | |
if (services.program.isSourceFileDefaultLibrary(sourceFile)) { | |
context.report({ node, messageId: 'noFunctionConstructor' }); | |
return; | |
} | |
} |
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.
LGTM! If you want to do that refactor in this PR I'd happily approve. Or we can leave it as a good first issue
followup. Either way.
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.
Let's open a followup with good first issue
;)
packages/eslint-plugin/src/rules/prefer-promise-reject-errors.ts
Outdated
Show resolved
Hide resolved
packages/eslint-plugin/tests/rules/prefer-promise-reject-errors.test.ts
Outdated
Show resolved
Hide resolved
packages/eslint-plugin/src/rules/prefer-promise-reject-errors.ts
Outdated
Show resolved
Hide resolved
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.
This looks lovely, thanks! 🙌
No blocking requests (other than the "guarantee" nit) from me. Just some touchup suggestions. Feel free to wontfix or do them, and then we can merge. Or if you don't have time I'll take another look soon. Cheers!
packages/eslint-plugin/docs/rules/prefer-promise-reject-errors.md
Outdated
Show resolved
Hide resolved
Co-authored-by: Josh Goldberg ✨ <git@joshuakgoldberg.com>
ad4dc75
to
895f1b5
Compare
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.
Sorry, two blocking requests:
- The variable readability change actually introduced a performance regression - lmk if the suggestion doesn't make sense?
- Apologies, I missed commenting on a couple of missing test cases
Since I already approved I do feel bad now requesting changes. If you don't have energy+time then no worries. I can apply these soon.
packages/eslint-plugin/src/rules/prefer-promise-reject-errors.ts
Outdated
Show resolved
Hide resolved
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.
PR Checklist
Overview
I tried to migrate the original rule with only type information added (it allows to detect
PromiseConstructor
like andError
like variables)Also I moved
isErrorLike
function to thetype-utils
package (I hope it's the right place for this function) as its logic may be reused both inprefer-promise-reject-errors
andno-throw-literal
I copied incorrect and correct examples from
no-throw-literal
because I found them applicable. But maybe there are too many examples for this rule