-
-
Notifications
You must be signed in to change notification settings - Fork 2.8k
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): [no-unnecessary-type-parameters] initial implementation #8173
feat(eslint-plugin): [no-unnecessary-type-parameters] initial implementation #8173
Conversation
Thanks for the PR, @danvk! 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. |
7ed4c77
to
c2384b3
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.
Your tweet about carving out dedicated time to finish this inspired me to carve out some time to understand how it works. It's not what I expected! But I think it's fine for now. See my comments / questions. Some more clarifying comments would be helpful.
packages/eslint-plugin/src/rules/no-unnecessary-type-parameters.ts
Outdated
Show resolved
Hide resolved
packages/eslint-plugin/src/rules/no-unnecessary-type-parameters.ts
Outdated
Show resolved
Hide resolved
Question: what's the motivation for counting the references to |
@Josh-Cena see discussion about return types here: #8173 (review). Depending on |
This rule was recently added to typescript-eslint and still considered experimental. | ||
It might change significantly between minor versions. | ||
Please try it out and give us feedback! | ||
::: |
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.
From chats with @bradzacher and @Josh-Cena: we're roughly ready to merge this rule, but it's still somewhat experimental / something-we-haven't-tried-ourselves-before. So instead of putting in strict
for now I'll add this notice and file a followup to move to strict
.
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.
(for posterity: the chats were about adding a notice; I felt icky after the fact about both having a notice and leaving it in strict
)
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.
OK! I chatted around internally and we're happy to try this out as-is. It's pretty early stage (and pretty different from previous implementations) so we're going to give it a warning notice and leave it out of the strict
preset for a bit. Time to start trying it out on our own projects! 🚀
Thanks again for getting this started and working with us throughout the PR @danvk. I'm really excited both about the rule and that we got an excuse to work together! 🙂
Thanks for taking over this PR and getting it merged, @JoshuaKGoldberg! I'm definitely curious to see what sort of feedback we get on it. |
…ntation (typescript-eslint#8173) * new rule, pairing w/ josh * start adding tests, discover some problesm * failing testgs * very simple version that fails with inferred return types * some processing of inferred return types * try to add inferred usages to count * 11/12 passing! * 12/12 pass * weird circular JSON error * oops * add test with inferred tuple type * add test with inferred tuple type * failing test with inferred object type * descend into object types * copy over another test * failing test case on method * Run on MethodDefinition * add TODO * comment * re-enable invalid eslint-plugin-etc test * port one more * shadowing test case * port one more test * port over DefinitelyTyped-tools tests; two failing * resolve one failure * resolve second failure * enable two more tests * one failing test from eslint-plugin-etc * one more failing test * full port of eslint-plugin-etc tests * one failing test from ETS post * fix previous error, expose a new one with a test * resolve inferred return types on methods * add both() function to test cases * enable eslint rule, cleanup * cleanup, add docs * add to rules list * generate configs * update tests, docs * Update packages/eslint-plugin/docs/rules/no-unnecessary-type-parameters.md Co-authored-by: Josh Goldberg ✨ <git@joshuakgoldberg.com> * Update packages/eslint-plugin/tests/rules/no-unnecessary-type-parameters.test.ts Co-authored-by: Josh Goldberg ✨ <git@joshuakgoldberg.com> * fix(utils): improve error message on typed rule with invalid parser (typescript-eslint#8146) * feat(utils): throw error on typed rule with invalid parser * Switch to more informative error message * fix tests * chore: enable no-dynamic-delete internally (typescript-eslint#7954) * chore: rename release.ts to release.mts (typescript-eslint#8204) * chore: rename release.ts to release.mts * Update tsconfig.eslint.json Co-authored-by: auvred <61150013+auvred@users.noreply.github.com> --------- Co-authored-by: auvred <61150013+auvred@users.noreply.github.com> * chore: enable eslint-plugin-jsdoc internally (typescript-eslint#8145) * chore: enable eslint-plugin-jsdoc internally * Disable jsdoc/check-param-names, with link to issue * Sort jsdoc rule disables and add links to issues * Switch typescript-estree-import.ts to line comments * docs: document allowAutomaticSingleRunInference (typescript-eslint#8138) * docs: document allowAutomaticSingleRunInference * so 'no' need * chore: prevent a11y-alt-text-bot workflow when author is a bot (typescript-eslint#8212) * chore: prevent a11y-alt-text-bot workflow when author is a bot * Update .github/workflows/a11y-alt-bot.yml --------- Co-authored-by: Josh Goldberg ✨ <git@joshuakgoldberg.com> * chore(typescript-estree): remove unnecessary old snapshots (typescript-eslint#8198) * chore(typescript-estree): remove unnecessary old snapshots Co-authored-by: Brad Zacher <brad.zacher@gmail.com> * chore: remove unused jest include patterns --------- Co-authored-by: Brad Zacher <brad.zacher@gmail.com> * fix(eslint-plugin): [no-non-null-assertion] provide valid fix when member access is on next line (typescript-eslint#8185) * fix(eslint-plugin): [no-non-null-assertion] provide valid fix when member access is on next line * test: add new case * fix(eslint-plugin): [no-unnecessary-condition] improve checking optional callee (typescript-eslint#8178) * fix(eslint-plugin): [prefer-readonly] support modifiers of unions and intersections (typescript-eslint#8169) * fix(eslint-plugin): [switch-exhaustiveness-check] fix new allowDefaultCaseForExhaustiveSwitch option (typescript-eslint#8176) * fix(allowDefaultCaseForExhaustiveSwitch): rule * chore: format * fix: add containsNonLiteralType * chore: cleanup * refactor: use type flags instead of strings * Update packages/eslint-plugin/src/rules/switch-exhaustiveness-check.ts * Update packages/eslint-plugin/src/rules/switch-exhaustiveness-check.ts --------- Co-authored-by: Josh Goldberg ✨ <git@joshuakgoldberg.com> * chore(deps): update dependency tsx to v4.7.0 (typescript-eslint#8162) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * chore: fix yargs call in release script (typescript-eslint#8221) * chore: fix test formatting in prefer-readonly.test.ts (typescript-eslint#8223) * chore(release): publish 6.18.1 * feat(eslint-plugin): [prefer-promise-reject-errors] add rule (typescript-eslint#8011) * feat(eslint-plugin): [prefer-promise-reject-errors] new rule! * test: ~100% coverage * docs: add rule docs * test: add some cases * chore: lint --fix * chore: reformat tests * feat: add support for literal computed reject name * chore: lint --fix * refactor: get rid of one @ts-expect-error * docs: refer to the original rule description * test: add few cases * docs: remove some examples * refactor: move check if symbol is from default lib or not to new fn * refactor: assert that rejectVariable is non-nullable * chore: remove assertion in skipChainExpression * test: specify error ranges for invalid test cases * chore: format tests * chore: remove unused check if variable reference is read or not * chore: include rule to `strict-type-checked` config * refactor: simplify isSymbolFromDefaultLibrary * chore: remove ts-expect-error comment * feat: add checks for Promise child classes and unions/intersections * Update packages/eslint-plugin/docs/rules/prefer-promise-reject-errors.md Co-authored-by: Josh Goldberg ✨ <git@joshuakgoldberg.com> * refactor: `program` -> `services.program` * refactor: split unreadable if condition * docs: simplify examples * refactor: rename `isBuiltinSymbolLike.ts` -> `builtinSymbolLikes.ts` * perf: get type of `reject` callee lazily * test: add cases with arrays,never,unknown * feat: add support for `Readonly<Error>` and similar * chore: fix lint issues --------- Co-authored-by: Josh Goldberg ✨ <git@joshuakgoldberg.com> * docs: base Testing Rules documentation (typescript-eslint#8033) * docs: base Testing Rules documentation * fix(eslint-plugin): add no-unsafe-unary-minus, prefer-destructuring to disable-type-checked (typescript-eslint#8038) fix: add no-unsafe-unary-minus, prefer-destructuring to disable-type-checked * docs: testing rules review changes + build callout * docs(eslint-plugin): [require-array-sort-compare] sync rule description (typescript-eslint#8061) * chore: resolve internal lint issues with new no-useless-template-literals rule (typescript-eslint#8060) * docs(eslint-plugin): [require-array-sort-compare] generalize sort method names (typescript-eslint#8062) docs: streamline * chore: update sponsors (typescript-eslint#8069) Co-authored-by: typescript-eslint[bot] <typescript-eslint[bot]@users.noreply.github.com> * Update docs/contributing/local-development/Local_Linking.mdx Co-authored-by: Josh Goldberg ✨ <git@joshuakgoldberg.com> * docs: changed section name + callout type from caution to note --------- Co-authored-by: Josh Goldberg ✨ <git@joshuakgoldberg.com> Co-authored-by: auvred <61150013+auvred@users.noreply.github.com> Co-authored-by: James <5511220+Zamiell@users.noreply.github.com> Co-authored-by: typescript-eslint[bot] <53356952+typescript-eslint[bot]@users.noreply.github.com> Co-authored-by: typescript-eslint[bot] <typescript-eslint[bot]@users.noreply.github.com> Co-authored-by: Gabriel Costa Moura <drt69727@MAC452093-M.local> * feat(eslint-plugin): [no-array-delete] add new rule (typescript-eslint#8067) * feat(eslint-plugin): [no-array-delete] add new rule * small refactor * add more cases * fix docs * fix message * use suggestion instead of fix * added more test cases * remove redundant condition * keep comments * docs: force space after await in no-floating-promises snippet (typescript-eslint#8228) force space after await * feat(eslint-plugin): [no-useless-template-literals] add fix suggestions (typescript-eslint#8065) * feat(eslint-plugin): [no-useless-template-literals] add fix suggestions * change message * add quasis to cspell * add some test cases * use fix instead of suggestion * docs: link version in website header to GitHub release (typescript-eslint#8236) * fix(typescript-estree): add JSDocParsingMode enum merge for typescript/lib/tsserverlibrary (typescript-eslint#8193) * fix(eslint-plugin): [no-unnecessary-type-assertion] detect unnecessary non-null-assertion on a call expression (typescript-eslint#8143) * feat(eslint-plugin): [no-unnecessary-type-assertion] add `Identifier` check * feat(eslint-plugin): [no-unnecessary-type-assertion] update fixer for `CallExpression` * feat(eslint-plugin): [no-unnecessary-type-assertion] add test case * feat(eslint-plugin): [no-unnecessary-type-assertion] fit more cases * feat(eslint-plugin): [no-unnecessary-type-assertion] add valid test cases * fix: fix a gap and add tests * fix: typo * fix(typescript-estree): disallow `using` as the variable keyword for `for..in` loops (typescript-eslint#7649) Co-authored-by: Brad Zacher <brad.zacher@gmail.com> * fix(eslint-plugin): [no-unnecesary-type-assertion] treat unknown/any as nullable (typescript-eslint#8089) Co-authored-by: Brad Zacher <brad.zacher@gmail.com> * fix(typescript-estree): fix incorrect backwards-compat augmentation in TS 5.3 (typescript-eslint#8181) * chore: make lint job use eslint-plugin outputs as inputs (typescript-eslint#8245) * chore(release): publish 6.19.0 * fix(type-utils): preventing isUnsafeAssignment infinite recursive calls (typescript-eslint#8237) * fix(type-utils): preventing isUnsafeAssignment infinite recursive calls * chore: apply reviews * fix(eslint-plugin): [no-unnecessary-condition] fix false positive for type variable (typescript-eslint#8235) * fix(eslint-plugin): [no-unnecessary-condition] fix false positive for type variable * chore: simplify test cases * chore(release): publish 6.19.1 * fix(eslint-plugin): [no-useless-template-literals] incorrect bigint autofix result (typescript-eslint#8283) * docs: underline URLs, change contrast in syntax highlighting (typescript-eslint#8225) * Add underlines on all links other than menu, table of contents * Fix comment in css Include next page in comment as I forgot to include it beforehand * Add comment whitespace * Remove underlines from navbar, buttons * Fix CSS in blog page causing headers, sidebar links to be underlined * Alter CSS to change only anchor elements inside .markdown class * Update styles to change color contrast in syntax highlighting * chore: update sponsors (typescript-eslint#8303) Co-authored-by: typescript-eslint[bot] <typescript-eslint[bot]@users.noreply.github.com> * docs: add `import/no-unresolved` to perf troubleshooting docs (typescript-eslint#8190) * feat(eslint-plugin): [member-ordering] allow easy reuse of the default ordering (typescript-eslint#8248) * docs: show all articles in sidebar, and a missing truncate (typescript-eslint#8306) * chore: enable prefer-nullish-coalescing internally (typescript-eslint#7955) * chore: enable prefer-nullish-calescing internally * A couple complaints * One last complaint * Enable ignoreConditionalTests * fix(eslint-plugin): [prefer-nullish-coalescing] treat any/unknown as non-nullable (typescript-eslint#8262) * fix(eslint-plugin): [prefer-nullish-coalescing] treat any/unknown as non-nullable * chore: rm unrelated changes * test: add declarations of 'y' variable * fix(eslint-plugin): [no-useless-template-literals] report Infinity & NaN (typescript-eslint#8295) * fix(eslint-plugin): [no-useless-template-literals] report Infinity & NaN Closes typescript-eslint#8294 * remove unnecessary tests * chore(deps): update react (typescript-eslint#8042) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * chore(eslint-plugin): fix typos in schema definitions (typescript-eslint#8311) chore: Fix typos in schema definitions * chore: fix broken and outdated links (typescript-eslint#8264) * fix(eslint-plugin): [prefer-readonly] disable checking accessors (typescript-eslint#8300) * Disable checking accessors for prefer-readonly * Granular accessor tests * Update packages/eslint-plugin/src/rules/prefer-readonly.ts * fix: formatting and || for isModifierFlagSet suggestion --------- Co-authored-by: Josh Goldberg ✨ <git@joshuakgoldberg.com> * chore(release): publish 6.20.0 * chore(eslint-plugin): [no-unused-vars] remove unused nested TSModuleDeclaration rule listener (typescript-eslint#8279) * fix(eslint-plugin): [no-unused-vars] don't report on types referenced in export assignment expression (typescript-eslint#8265) * docs(eslint-plugin): remove `fixable` and `hasSuggestions` from rules that don't provide them (typescript-eslint#8253) * feat(typescript-estree): forbid duplicated accessibility modifiers (typescript-eslint#8257) * test(eslint-plugin): assert that `ts`/`tsx` code blocks in docs are syntactically valid (typescript-eslint#8142) * test(eslint-plugin): assert that `ts`/`tsx` code blocks in docs are syntactically valid * revert unintended changes in space-before-blocks.md * chore: shorten examples in consistent-type-assertions.md * refactor: do not parse md file again * docs: more consistent examples for consistent-type-assertions * docs: convert `js` code blocks to `ts` * Update packages/eslint-plugin/tests/docs.test.ts Co-authored-by: Josh Goldberg ✨ <git@joshuakgoldberg.com> * chore: use regex instead of startsWith * chore: fix few codesamples --------- Co-authored-by: Josh Goldberg ✨ <git@joshuakgoldberg.com> * chore(deps): update dependency @swc/jest to v0.2.31 (typescript-eslint#8313) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * chore(deps): update dependency @swc/core to v1.3.106 (typescript-eslint#8219) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * chore(deps): update babel to v7.23.9 (typescript-eslint#8199) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * chore: unpin primary node version in ci (typescript-eslint#8167) * fix(eslint-plugin): [switch-exhaustiveness-check] better support for intersections, infinite types, non-union values (typescript-eslint#8250) * feat(eslint-plugin): [switch-exhaustiveness-check] better support for intersections, infinite types, non-union values * chore: try to fix weird diff with main * refactor: no need to collect missing branches in function * fix: provide valid fixes for unique symbols * fix: valid fixes for unique symbols + few test cases for enums * docs: add /maintenance/team page (typescript-eslint#8057) * docs: add /maintenance/team page * Apply Brad's requested changes * Styles and social links * Mentioned Contributor Tiers * Added Sponsor Us section * chore(deps): update dependency eslint-plugin-jest to v27.6.3 (typescript-eslint#230) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * chore(deps): update dependency netlify to v13.1.13 (typescript-eslint#231) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * chore(deps): update dependency yargs to v17.7.2 (typescript-eslint#233) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * chore(deps): update dependency @prettier/sync to v0.5.0 (typescript-eslint#235) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * chore(deps): update dependency @types/node to v20.11.9 (typescript-eslint#236) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * chore(deps): update dependency chai to v4.4.1 (typescript-eslint#237) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * chore(deps): update dependency @swc/core to v1.3.107 (typescript-eslint#238) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * chore(deps): update dependency esbuild to ~0.20.0 (typescript-eslint#240) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * Alphabetized CSS (sorry StyleShit 😛) * Update packages/website/src/components/team/TeamBio.module.css Co-authored-by: StyleShit <32631382+StyleShit@users.noreply.github.com> * The rest of .serviceIconLink * <hr /> * Shrunk images and used my newer colors --------- Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: StyleShit <32631382+StyleShit@users.noreply.github.com> * chore: move generate-configs to repo-tools (typescript-eslint#8329) * chore: add `typescript-eslint` package scaffold (typescript-eslint#8296) * fix(eslint-plugin): [consistent-type-imports] dont report on types used in export assignment expressions (typescript-eslint#8332) * fix(eslint-plugin): [no-unnecessary-condition] handle left-hand optional with exactOptionalPropertyTypes option (typescript-eslint#8249) * fix(eslint-plugin): [no-unnecessary-condition] handle left-hand optional with exactOptionalPropertyTypes option * typo: remove the 's' --------- Co-authored-by: Josh Goldberg <git@joshuakgoldberg.com> * chore: remove unnecessary eslint-disable comments (typescript-eslint#8336) * chore: update sponsors (typescript-eslint#8340) Co-authored-by: typescript-eslint[bot] <typescript-eslint[bot]@users.noreply.github.com> * chore: bump eslint versions (typescript-eslint#8338) * chore: cleanup test-utils naming/locations (typescript-eslint#8341) * chore(website): [playground] add twoslash queries (typescript-eslint#8119) * fix(eslint-plugin): [class-literal-property-style] allow getter when same key setter exists (typescript-eslint#8277) * feat(utils): improve eslint types (typescript-eslint#8344) * feat: export plugin metadata (typescript-eslint#8331) * feat: export plugin metadata * Update Config.ts * feat(eslint-plugin): add rule prefer-find (typescript-eslint#8216) * Add rule prefer-find * address lots of stuff * remove console statement * tweaks * extract fix to function * improve behavior around nulls * add comments around array indexing checks * messages were backwards * filter syntax * formatting * add extra comma operator test * pr feedback round 2 * Fix the the Co-authored-by: auvred <61150013+auvred@users.noreply.github.com> * fix up imports * address intersections of arrays --------- Co-authored-by: auvred <61150013+auvred@users.noreply.github.com> * chore(deps): update dependency @prettier/sync to ^0.5.0 (typescript-eslint#8342) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * chore(deps): update dependency clsx to v2.1.0 (typescript-eslint#8343) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * chore(deps): update dependency netlify to v13.1.14 (typescript-eslint#8321) chore(deps): update dependency netlify to v13.1.13 Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * chore(deps): update dependency lint-staged to v15.2.0 (typescript-eslint#8043) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Josh Goldberg ✨ <git@joshuakgoldberg.com> * chore(deps): update dependency prettier to v3.2.4 (typescript-eslint#8127) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * chore(deps): update dependency markdownlint-cli to ^0.38.0 (typescript-eslint#8159) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Josh Goldberg ✨ <git@joshuakgoldberg.com> * chore(deps): update dependency monaco-editor to ~0.45.0 (typescript-eslint#8161) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Josh Goldberg ✨ <git@joshuakgoldberg.com> * chore(deps): update dependency react-resizable-panels to ^0.0.63 (typescript-eslint#8328) * chore(deps): update dependency react-resizable-panels to ^0.0.63 * Updated props for '*Percentage' --------- Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Josh Goldberg <git@joshuakgoldberg.com> * chore(deps): update dependency lint-staged to v15.2.1 (typescript-eslint#8350) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * fix(ast-spec): add `JSXElement` type to the `JSXAttribute['value']` (typescript-eslint#8285) * fix(ast-spec): add `JSXElement` type to the `JSXAttribute['value']` * test: add fixtures * chore: sync snapshots * fix(eslint-plugin): [no-unnecessary-type-assertion] provide valid fixes for assertions with extra tokens before `as` keyword (typescript-eslint#8326) * fix(eslint-plugin): [no-unnecessary-type-assertion] provide valid fixes for assertions with extra tokens before `as` keyword * fix: provide fixes for angle bracket assertions when there're tokens inside * chore(eslint-plugin): [no-invalid-void-type] fix `Options` typing to reflect `minItems: 1` (typescript-eslint#8312) * fix(rule-tester): fix a phantom dependency on the "semver" package (typescript-eslint#8260) * fix(rule-tester): Fix a phantom dependency on the "semver" package in DependencyConstraint.d.ts * Update packages/rule-tester/src/types/DependencyConstraint.ts Co-authored-by: Josh Goldberg ✨ <git@joshuakgoldberg.com> * Remove 'extends Options' --------- Co-authored-by: Josh Goldberg ✨ <git@joshuakgoldberg.com> Co-authored-by: Brad Zacher <brad.zacher@gmail.com> * feat: allow `parserOptions.project: false` (typescript-eslint#8339) * chore(deps): update dependency @swc/jest to v0.2.34 (typescript-eslint#8363) chore(deps): update dependency @swc/jest to v0.2.33 Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * chore(deps): update dependency ignore to v5.3.1 (typescript-eslint#8360) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * chore(deps): update dependency @types/node to v20.11.15 (typescript-eslint#8356) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * chore(deps): update dependency @types/react to v18.2.51 (typescript-eslint#8361) chore(deps): update dependency @types/react to v18.2.49 Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Josh Goldberg ✨ <git@joshuakgoldberg.com> * chore(deps): update dependency netlify to v13.1.14 (typescript-eslint#8353) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * chore(deps): update dependency webpack to v5.90.0 (typescript-eslint#8359) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Josh Goldberg ✨ <git@joshuakgoldberg.com> * chore(deps): update dependency @babel/eslint-parser to v7.23.10 (typescript-eslint#8349) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Josh Goldberg ✨ <git@joshuakgoldberg.com> * chore(deps): update dependency @types/jest to v29.5.12 (typescript-eslint#8371) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * chore(deps): update dependency markdownlint-cli to ^0.39.0 (typescript-eslint#8354) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Josh Goldberg ✨ <git@joshuakgoldberg.com> * chore(deps): update dependency prettier to v3.2.4 (typescript-eslint#8357) * chore(deps): update dependency prettier to v3.2.4 * chore: update formatting after prettier upgrade --------- Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: JamesHenry <james@henry.sc> * code review * Apply suggestions from code review * Fixed up the tsNode.body complaint * Apply suggestions from code review * Generated configs, and touched up docs * Let's make it strict * Account for type parameters used as type arguments * Tweaked docs * Correct lint and snapshot issues * Aha, one more T * Fixed up last test cases * Reworked to be types-only * Repo is passing build, lint, and typecheck * Aha, no need for infinite type checking * Updated snapshot * Revert "Aha, no need for infinite type checking" This reverts commit 581937d. * Simplier general/return logic * Wow so much simpler * Adjusted comments * Forward along asRepeatedType * List -> Item * fetchJson, alas * Initial pass of the AST check * chore: add missing output: nulls in prefer-optional-chain.test.ts Result of merging a few PRs into main. * skipConstituentsUpward optimization * Docs and naming improvements * Allow introduced convert.test.ts complaint * Ah, yes, Prettier * Disable comment for helpers isNodeOfTypeWithConditions * Remove from strict and add an experimental notice * shakes fist at nx --------- Co-authored-by: Josh Goldberg ✨ <git@joshuakgoldberg.com> Co-authored-by: auvred <61150013+auvred@users.noreply.github.com> Co-authored-by: Hao Cheng <hcheng636@gmail.com> Co-authored-by: Brad Zacher <brad.zacher@gmail.com> Co-authored-by: YeonJuan <yeonjuan93@naver.com> Co-authored-by: James <5511220+Zamiell@users.noreply.github.com> Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: typescript-eslint[bot] <typescript-eslint[bot]@users.noreply.github.com> Co-authored-by: Gabriel Costa <gabriel.moura6@fatec.sp.gov.br> Co-authored-by: typescript-eslint[bot] <53356952+typescript-eslint[bot]@users.noreply.github.com> Co-authored-by: Gabriel Costa Moura <drt69727@MAC452093-M.local> Co-authored-by: StyleShit <32631382+StyleShit@users.noreply.github.com> Co-authored-by: kirkwaiblinger <53019676+kirkwaiblinger@users.noreply.github.com> Co-authored-by: Flo Edelmann <git@flo-edelmann.de> Co-authored-by: LJX <11309921+lvjiaxuan@users.noreply.github.com> Co-authored-by: Steven <ssteven19@kimo.com> Co-authored-by: Joshua Chen <sidachen2003@gmail.com> Co-authored-by: James Henry <james@henry.sc> Co-authored-by: Lucas Amberg <102396588+lucas-amberg@users.noreply.github.com> Co-authored-by: Alex Parloti <parloti@gmail.com> Co-authored-by: Edwin Kofler <edwin@kofler.dev> Co-authored-by: NanderTGA <65074195+NanderTGA@users.noreply.github.com> Co-authored-by: James Browning <thejamesernator@gmail.com> Co-authored-by: Khairul Azhar Kasmiran <kazarmy@gmail.com> Co-authored-by: Pete Gonzalez <4673363+octogonz@users.noreply.github.com>
PR Checklist
Overview
See linked issue. I've incorporated the tests from my blog post and all the existing rules. We sometimes (but not always) agree with them.
I'm pretty happy with how this turned out! The logic winds up being pretty straightforward: count the number of times each type parameter is referenced, whether explicitly or implicitly in an inferred return type. If that's exactly one, then report an issue.
One fun discovery: I always thought that this rule had some unavoidable false positives, e.g. my
both
function from cartant/eslint-plugin-etc#15. But looking at that again a few years later, I think it's a true positive that can be rewritten to avoid breaking the golden rule:❌ Incorrect
✅ Correct
🎉
Notes from Josh (April 2024): Dan and I chatted and I'm pitching in to help get this to review state. The design is actually more intricate than we'd initially hoped:
The logic is still straightforward: recursively descend into types, kind of like how scope analyzer does in AST-land. But the edge cases were quite tricky.
💖