Skip to content

Commit

Permalink
feat(eslint-plugin): [no-unnecessary-type-parameters] initial impleme…
Browse files Browse the repository at this point in the history
…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 ✨ <[email protected]>

* Update packages/eslint-plugin/tests/rules/no-unnecessary-type-parameters.test.ts

Co-authored-by: Josh Goldberg ✨ <[email protected]>

* 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 <[email protected]>

---------

Co-authored-by: auvred <[email protected]>

* 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 ✨ <[email protected]>

* chore(typescript-estree): remove unnecessary old snapshots (typescript-eslint#8198)

* chore(typescript-estree): remove unnecessary old snapshots

Co-authored-by: Brad Zacher <[email protected]>

* chore: remove unused jest include patterns

---------

Co-authored-by: Brad Zacher <[email protected]>

* 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 ✨ <[email protected]>

* 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 ✨ <[email protected]>

* 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 ✨ <[email protected]>

* 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 ✨ <[email protected]>

* docs: changed section name + callout type from caution to note

---------

Co-authored-by: Josh Goldberg ✨ <[email protected]>
Co-authored-by: auvred <[email protected]>
Co-authored-by: James <[email protected]>
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 <[email protected]>

* 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 <[email protected]>

* fix(eslint-plugin): [no-unnecesary-type-assertion] treat unknown/any as nullable (typescript-eslint#8089)

Co-authored-by: Brad Zacher <[email protected]>

* 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 ✨ <[email protected]>

* 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 ✨ <[email protected]>

* chore: use regex instead of startsWith

* chore: fix few codesamples

---------

Co-authored-by: Josh Goldberg ✨ <[email protected]>

* 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 <[email protected]>

* 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 <[email protected]>

* 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 <[email protected]>

* 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 <[email protected]>

* fix up imports

* address intersections of arrays

---------

Co-authored-by: auvred <[email protected]>

* 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 ✨ <[email protected]>

* 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 ✨ <[email protected]>

* 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 ✨ <[email protected]>

* 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 <[email protected]>

* 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 ✨ <[email protected]>

* Remove 'extends Options'

---------

Co-authored-by: Josh Goldberg ✨ <[email protected]>
Co-authored-by: Brad Zacher <[email protected]>

* 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 ✨ <[email protected]>

* 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 ✨ <[email protected]>

* 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 ✨ <[email protected]>

* 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 ✨ <[email protected]>

* 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 <[email protected]>

* 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 ✨ <[email protected]>
Co-authored-by: auvred <[email protected]>
Co-authored-by: Hao Cheng <[email protected]>
Co-authored-by: Brad Zacher <[email protected]>
Co-authored-by: YeonJuan <[email protected]>
Co-authored-by: James <[email protected]>
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 <[email protected]>
Co-authored-by: typescript-eslint[bot] <53356952+typescript-eslint[bot]@users.noreply.github.com>
Co-authored-by: Gabriel Costa Moura <[email protected]>
Co-authored-by: StyleShit <[email protected]>
Co-authored-by: kirkwaiblinger <[email protected]>
Co-authored-by: Flo Edelmann <[email protected]>
Co-authored-by: LJX <[email protected]>
Co-authored-by: Steven <[email protected]>
Co-authored-by: Joshua Chen <[email protected]>
Co-authored-by: James Henry <[email protected]>
Co-authored-by: Lucas Amberg <[email protected]>
Co-authored-by: Alex Parloti <[email protected]>
Co-authored-by: Edwin Kofler <[email protected]>
Co-authored-by: NanderTGA <[email protected]>
Co-authored-by: James Browning <[email protected]>
Co-authored-by: Khairul Azhar Kasmiran <[email protected]>
Co-authored-by: Pete Gonzalez <[email protected]>
  • Loading branch information
1 parent f138ffd commit c2fc0ae
Show file tree
Hide file tree
Showing 19 changed files with 1,206 additions and 14 deletions.
1 change: 1 addition & 0 deletions eslint.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ export default tseslint.config(
'error',
{ allowConstantLoopConditions: true },
],
'@typescript-eslint/no-unnecessary-type-parameters': 'error',
'@typescript-eslint/no-var-requires': 'off',
'@typescript-eslint/prefer-literal-enum-member': [
'error',
Expand Down
115 changes: 115 additions & 0 deletions packages/eslint-plugin/docs/rules/no-unnecessary-type-parameters.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
---
description: 'Disallow type parameters that only appear once.'
---

import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';

> 🛑 This file is source code, not the primary documentation location! 🛑
>
> See **https://typescript-eslint.io/rules/no-unnecessary-type-parameters** for documentation.
This rule forbids type parameters that only appear once in a function, method, or class definition.

Type parameters relate two types.
If a type parameter only appears once, then it is not relating anything.
It can usually be replaced with explicit types such as `unknown`.

At best unnecessary type parameters make code harder to read.
At worst they can be used to disguise unsafe type assertions.

:::warning Early Stage
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!
:::

## Examples

<Tabs>
<TabItem value="❌ Incorrect">

```ts
function second<A, B>(a: A, b: B): B {
return b;
}

function parseJSON<T>(input: string): T {
return JSON.parse(input);
}

function printProperty<T, K extends keyof T>(obj: T, key: K) {
console.log(obj[key]);
}
```

</TabItem>
<TabItem value="✅ Correct">

```ts
function second<B>(a: unknown, b: B): B {
return b;
}

function parseJSON(input: string): unknown {
return JSON.parse(input);
}

function printProperty<T>(obj: T, key: keyof T) {
console.log(obj[key]);
}

// T appears twice: in the type of arg and as the return type
function identity<T>(arg: T): T {
return arg;
}

// T appears twice: "keyof T" and in the inferred return type (T[K]).
// K appears twice: "key: K" and in the inferred return type (T[K]).
function getProperty<T, K extends keyof T>(obj: T, key: K) {
return obj[key];
}
```

</TabItem>
</Tabs>

## Limitations

Note that this rule allows any type parameter that is used multiple times, even if those uses are via a type argument.
For example, the following `T` is used multiple times by virtue of being in an `Array`, even though its name only appears once after declaration:

```ts
declare function createStateHistory<T>(): T[];
```

This is because the type parameter `T` relates multiple methods in the `T[]` together, making it used more than once.

Therefore, this rule won't report on type parameters used as a type argument.
That includes type arguments given to global types such as `Array` (including the `T[]` shorthand and in tuples), `Map`, and `Set`.

## When Not To Use It

This rule will report on functions that use type parameters solely to test types, for example:

```ts
function assertType<T>(arg: T) {}

assertType<number>(123);
assertType<number>('abc');
// ~~~~~
// Argument of type 'string' is not assignable to parameter of type 'number'.
```

If you're using this pattern then you'll want to disable this rule on files that test types.

## Further Reading

- TypeScript handbook: [Type Parameters Should Appear Twice](https://microsoft.github.io/TypeScript-New-Handbook/everything/#type-parameters-should-appear-twice)
- Effective TypeScript: [The Golden Rule of Generics](https://effectivetypescript.com/2020/08/12/generics-golden-rule/)

## Related To

- eslint-plugin-etc's [`no-misused-generics`](https://github.com/cartant/eslint-plugin-etc/blob/main/docs/rules/no-misused-generics.md)
- wotan's [`no-misused-generics`](https://github.com/fimbullinter/wotan/blob/master/packages/mimir/docs/no-misused-generics.md)
- DefinitelyTyped-tools' [`no-unnecessary-generics`](https://github.com/microsoft/DefinitelyTyped-tools/blob/main/packages/eslint-plugin/docs/rules/no-unnecessary-generics.md)
1 change: 1 addition & 0 deletions packages/eslint-plugin/src/configs/all.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ export = {
'@typescript-eslint/no-unnecessary-type-arguments': 'error',
'@typescript-eslint/no-unnecessary-type-assertion': 'error',
'@typescript-eslint/no-unnecessary-type-constraint': 'error',
'@typescript-eslint/no-unnecessary-type-parameters': 'error',
'@typescript-eslint/no-unsafe-argument': 'error',
'@typescript-eslint/no-unsafe-assignment': 'error',
'@typescript-eslint/no-unsafe-call': 'error',
Expand Down
1 change: 1 addition & 0 deletions packages/eslint-plugin/src/configs/disable-type-checked.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ export = {
'@typescript-eslint/no-unnecessary-template-expression': 'off',
'@typescript-eslint/no-unnecessary-type-arguments': 'off',
'@typescript-eslint/no-unnecessary-type-assertion': 'off',
'@typescript-eslint/no-unnecessary-type-parameters': 'off',
'@typescript-eslint/no-unsafe-argument': 'off',
'@typescript-eslint/no-unsafe-assignment': 'off',
'@typescript-eslint/no-unsafe-call': 'off',
Expand Down
2 changes: 2 additions & 0 deletions packages/eslint-plugin/src/rules/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ import noUnnecessaryTemplateExpression from './no-unnecessary-template-expressio
import noUnnecessaryTypeArguments from './no-unnecessary-type-arguments';
import noUnnecessaryTypeAssertion from './no-unnecessary-type-assertion';
import noUnnecessaryTypeConstraint from './no-unnecessary-type-constraint';
import noUnnecessaryTypeParameters from './no-unnecessary-type-parameters';
import noUnsafeArgument from './no-unsafe-argument';
import noUnsafeAssignment from './no-unsafe-assignment';
import noUnsafeCall from './no-unsafe-call';
Expand Down Expand Up @@ -231,6 +232,7 @@ export default {
'no-unnecessary-type-arguments': noUnnecessaryTypeArguments,
'no-unnecessary-type-assertion': noUnnecessaryTypeAssertion,
'no-unnecessary-type-constraint': noUnnecessaryTypeConstraint,
'no-unnecessary-type-parameters': noUnnecessaryTypeParameters,
'no-unsafe-argument': noUnsafeArgument,
'no-unsafe-assignment': noUnsafeAssignment,
'no-unsafe-call': noUnsafeCall,
Expand Down
Loading

0 comments on commit c2fc0ae

Please sign in to comment.