8000 Repo: enable more `eslint-plugin-unicorn` rules internally · Issue #9623 · typescript-eslint/typescript-eslint · GitHub
[go: up one dir, main page]

Skip to content

Repo: enable more eslint-plugin-unicorn rules internally #9623

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

Closed
abrahamguo opened this issue Jul 23, 2024 · 31 comments · Fixed by #9916
Closed

Repo: enable more eslint-plugin-unicorn rules internally #9623

abrahamguo opened this issue Jul 23, 2024 · 31 comments · Fixed by #9916
Labels
accepting prs Go ahead, send a pull request that resolves this issue locked due to age Please open a new issue if you'd like to say more. See https://typescript-eslint.io/contributing. repo maintenance things to do with maintenance of the repo, and not with code/docs

Comments

@abrahamguo
Copy link
Contributor

Suggestion

Following up on #9523, I was looking through the eslint-plugin-unicorn rules that we do not have turned on internally, and I found these rules that might be beneficial to enable. Thoughts?

better-regex (26 occurrences)

docs

/([`$``])/g can be optimized to /([$```])/g.
eslint-plugin/src/rules/no-unnecessary-template-expression.ts:150
eslint-plugin/src/rules/no-useless-template-literals.ts:151

/(^|[^\`\`])"(?:``.|[^\`\`"\`r\`n])`"(?!`s`:)/ can be optimized to /(^|[^\`\`])"(?:``.|[^\`n\`r"\`\`])`"(?!`s`:)/.
website/src/prism/language/jsonc.js:11

/(^|[^\`\`])"(?:``.|[^\`\`"\`r\`n])`"(?=`s`:)/ can be optimized to /(^|[^\`\`])"(?:``.|[^\`n\`r"\`\`])`"(?=`s`:)/.
website/src/prism/language/jsonc.js:6

/[{}[`],]/ can be optimized to /[,[`]{}]/.
website/src/prism/language/jsonc.js:20

/[``/]`error`[``/]/ can be optimized to /[/``]`error`[/``]/.
ast-spec/tests/fixtures.test.ts:75

/[``^$.`+?()[`]{}|]/g can be optimized to /[$()`+.?[```]^{|}]/g.
eslint-plugin/src/util/escapeRegExp.ts:5

/`/`/.`|`/``[`s`S]`?(?:```/|$)/ can be optimized to /`/`/.`|`/``[`S`s]`?(?:```/|$)/.
website/src/prism/language/jsonc.js:16

/``(?!["])/gm can be optimized to /``(?!")/gm.
typescript-estree/tests/lib/parse.test.ts:60

/`$`{/g can be optimized to /`${/g.
eslint-plugin-internal/src/rules/plugin-test-formatting.ts:51

/`r`n|[`r`n`u2028`u2029]/ can be optimized to /`r`n|[`n`r`u2028`u2029]/.
utils/src/ast-utils/misc.ts:3

/&(?:#`d+|#x[`da-fA-F]+|[0-9a-zA-Z]+);/g can be optimized to /&(?:#`d+|#x[`dA-Fa-f]+|[`dA-Za-z]+);/g.
typescript-estree/src/node-utils.ts:450

/^([ ]`)/ can be optimized to /^( `)/.
eslint-plugin-internal/src/rules/plugin-test-formatting.ts:49

/^(`/?|)([`s`S]`?)((?:`.{1,2}|[^/]+?|)(`.[^./]`|))(?:[/]`)$/ can be optimized to /^(`/?|)([`S`s]`?)((?:`.{1,2}|[^/]+?|)(`.[^./]`|))`/`$/.
website-eslint/src/mock/path.js:55

/^"'['"]$/ can be optimized to /^"'["']$/.
scope-manager/tests/fixtures.test.ts:39

/^[(`w+:)``/]/ can be optimized to /^[`w()+/:``]/.
typescript-estree/src/create-program/describeFilePath.ts:18

/^[`([]/ can be optimized to /^[([`]/.
eslint-plugin/src/util/getWrappingFixer.ts:70

/^[=!]=/ can be optimized to /^[!=]=/.
eslint-plugin/src/rules/prefer-string-starts-ends-with.ts:16

/^[=?:]$/ can be optimized to /^[:=?]$/.
eslint-plugin/src/rules/space-infix-ops.ts:74

/^`/`/`/`/[ ]+@(`w+)[ ]`=[ ]`(.+)$/ can be optimized to /^`/{4} +@(`w+) `= `(.+)$/.
scope-manager/tests/fixtures.test.ts:38

/^`/`s`<reference`s`(types|path|lib)`s`=`s`"|'["|']/ can be optimized to /^`/`s`<reference`s`(types|path|lib)`s`=`s`"'|["'|]/.
eslint-plugin/src/rules/triple-slash-reference.ts:98

/^`s`(?:`/|``)``s`@ts-(?expect-error|ignore)(?.`)/ can be optimized to /^`s`[`/]``s`@ts-(?expect-er{2}or|ignore)(?.`)/.
eslint-plugin/src/rules/ban-ts-comment.ts:117

/^`s`(?:`/|``)``s`@ts-ignore/ can be optimized to /^`s`[`/]``s`@ts-ignore/.
eslint-plugin/src/rules/prefer-ts-expect-error.ts:28

/Cannot read file .+semanticInfo'/i can be optimized to /cannot read file .+semanticinfo'/i.
typescript-estree/tests/lib/semanticInfo.test.ts:286

/getParserServices(`(`s`[^,\`s)]+)`s`(,`s`false`s`)?`)/ can be optimized to /getParserServices(`(`s`[^\`s),]+)`s`(,`s`false`s`)?`)/.
eslint-plugin/tests/docs.test.ts:512

/import`s``{`s`TypeScriptWorker`s`}`s`from`s`['"].`/tsWorker['"];/ can be optimized to /import`s`{`s`TypeScriptWorker`s`}`s`from`s`["'].`/tsWorker["'];/.
website/tools/generate-website-dts.ts:75

catch-error-name (29 occurrences)

docs

The catch parameter e should be named error.
ast-spec/tests/fixtures.test.ts:140
parser/tests/lib/tsx.test.ts:15
repo-tools/src/generate-lib.mts:310
rule-schema-to-typescript-types/src/index.ts:51
scope-manager/tests/fixtures.test.ts:146
scope-manager/tests/fixtures.test.ts:160
typescript-estree/src/semantic-or-syntactic-errors.ts:42
website-eslint/build.ts:166
website/src/components/ESQueryFilter.tsx:25
website/src/components/ast/ASTViewer.tsx:31
website/src/components/hooks/useHashState.ts:43
website/src/components/hooks/useHashState.ts:102
website/src/components/hooks/useHashState.ts:132
website/src/components/hooks/useHashState.ts:172
website/src/components/lib/json.ts:19
website/src/components/lib/parseConfig.ts:23
website/src/components/lib/parseConfig.ts:47
website/src/components/lib/parseConfig.ts:77
website/src/components/linter/createLinter.ts:82
website/src/components/linter/createLinter.ts:149
website/src/components/linter/createLinter.ts:161
website/src/components/typeDetails/TypeInfo.tsx:86

The catch parameter err should be named error.
rule-tester/src/RuleTester.ts:622
rule-tester/src/utils/config-validator.ts:116
rule-tester/src/utils/config-validator.ts:197
website/plugins/generated-rule-docs/addESLintHashToCodeBlocksMeta.ts:57
website/src/components/editor/useSandboxServices.ts:137

The catch parameter ex should be named error.
eslint-plugin-internal/src/rules/plugin-test-formatting.ts:171
integration-tests/tools/integration-test-base.ts:155

custom-error-definition (4 occurrences)

docs

The name property should be set to AssertionError.
website-eslint/src/mock/assert.js:27

The name property should be set to NotSupportedError.
rule-schema-to-typescript-types/src/errors.ts:2

The name property should be set to TSError.
typescript-estree/src/node-utils.ts:702

The name property should be set to UnexpectedError.
rule-schema-to-typescript-types/src/errors.ts:14

error-message (1 occurrence)

docs

Pass a message to the Error constructor.
website-eslint/src/mock/assert.js:45

no-array-for-each (118 occurrences)

docs

Use for…of instead of .forEach(…).
ast-spec/tests/fixtures.test.ts:336
eslint-plugin/src/rules/adjacent-overload-signatures.ts:135
eslint-plugin/src/rules/ban-ts-comment.ts:186
eslint-plugin/src/rules/ban-tslint-comment.ts:37
eslint-plugin/src/rules/class-literal-property-style.ts:99
eslint-plugin/src/rules/comma-spacing.ts:180
eslint-plugin/src/rules/consistent-generic-constructors.ts:123
eslint-plugin/src/rules/consistent-type-definitions.ts:104
eslint-plugin/src/rules/lines-around-comment.ts:41
eslint-plugin/src/rules/lines-around-comment.ts:438
eslint-plugin/src/rules/member-delimiter-style.ts:340
eslint-plugin/src/rules/member-ordering.ts:320
eslint-plugin/src/rules/member-ordering.ts:354
eslint-plugin/src/rules/member-ordering.ts:359
eslint-plugin/src/rules/member-ordering.ts:657
eslint-plugin/src/rules/member-ordering.ts:700
eslint-plugin/src/rules/member-ordering.ts:872
eslint-plugin/src/rules/member-ordering.ts:1001
eslint-plugin/src/rules/naming-convention-utils/parse-options.ts:21
eslint-plugin/src/rules/naming-convention-utils/parse-options.ts:24
eslint-plugin/src/rules/naming-convention.ts:289
eslint-plugin/src/rules/naming-convention.ts:370
eslint-plugin/src/rules/naming-convention.ts:377
eslint-plugin/src/rules/naming-convention.ts:405
eslint-plugin/src/rules/no-duplicate-enum-values.ts:43
eslint-plugin/src/rules/no-inferrable-types.ts:253
eslint-plugin/src/rules/no-mixed-enums.ts:62
eslint-plugin/src/rules/no-type-alias.ts:344
eslint-plugin/src/rules/no-unnecessary-parameter-property-assignment.ts:147
eslint-plugin/src/rules/no-unnecessary-template-expression.ts:125
eslint-plugin/src/rules/no-unnecessary-type-parameters.ts:293
eslint-plugin/src/rules/no-unnecessary-type-parameters.ts:298
eslint-plugin/src/rules/no-use-before-define.ts:328
eslint-plugin/src/rules/no-use-before-define.ts:376
eslint-plugin/src/rules/no-useless-template-literals.ts:126
eslint-plugin/src/rules/prefer-enum-initializers.ts:29
eslint-plugin/src/rules/prefer-function-type.ts:157
eslint-plugin/src/rules/prefer-promise-reject-errors.ts:140
eslint-plugin/src/rules/prefer-readonly.ts:452
eslint-plugin/src/rules/prefer-readonly.ts:456
eslint-plugin/src/rules/prefer-ts-expect-error.ts:54
eslint-plugin/src/rules/return-await.ts:378
eslint-plugin/src/rules/return-await.ts:389
eslint-plugin/src/rules/space-infix-ops.ts:135
eslint-plugin/src/rules/triple-slash-reference.ts:65
eslint-plugin/src/rules/triple-slash-reference.ts:102
eslint-plugin/src/rules/unbound-method.ts:191
eslint-plugin/src/util/collectUnusedVariables.ts:460
eslint-plugin/src/util/collectUnusedVariables.ts:483
eslint-plugin/src/util/collectUnusedVariables.ts:500
eslint-plugin/tests/configs.test.ts:98
eslint-plugin/tests/docs.test.ts:223
eslint-plugin/tests/rules/indent/indent.test.ts:611
eslint-plugin/tests/rules/naming-convention/cases/createTestCases.ts:276
eslint-plugin/tests/rules/prefer-nullish-coalescing.test.ts:39
eslint-plugin/tests/rules/prefer-nullish-coalescing.test.ts:55
eslint-plugin/tests/util.test.ts:23
eslint-plugin/tests/util.test.ts:33
parser/tests/lib/services.test.ts:36
rule-tester/src/RuleTester.ts:378
rule-tester/src/RuleTester.ts:437
rule-tester/src/RuleTester.ts:458
rule-tester/src/RuleTester.ts:847
rule-tester/src/RuleTester.ts:1001
rule-tester/src/RuleTester.ts:1008
rule-tester/src/utils/SourceCodeFixer.ts:83
rule-tester/src/utils/config-validator.ts:143
rule-tester/src/utils/config-validator.ts:169
rule-tester/src/utils/config-validator.ts:193
rule-tester/src/utils/freezeDeeply.ts:7
rule-tester/src/utils/validationHelpers.ts:117
rule-tester/src/utils/validationHelpers.ts:118
scope-manager/src/ScopeManager.ts:55
scope-manager/src/ScopeManager.ts:56
scope-manager/src/ScopeManager.ts:58
scope-manager/src/referencer/ClassVisitor.ts:52
scope-manager/src/referencer/ClassVisitor.ts:70
scope-manager/src/referencer/ClassVisitor.ts:209
scope-manager/src/referencer/ClassVisitor.ts:251
scope-manager/src/referencer/ClassVisitor.ts:265
scope-manager/src/referencer/ClassVisitor.ts:330
scope-manager/src/referencer/PatternVisitor.ts:59
scope-manager/src/referencer/PatternVisitor.ts:84
scope-manager/src/referencer/Referencer.ts:74
scope-manager/src/referencer/Referencer.ts:270
scope-manager/src/referencer/TypeVisitor.ts:191
scope-manager/src/referencer/Visitor.ts:40
scope-manager/src/scope/ScopeBase.ts:364
scope-manager/src/scope/WithScope.ts:26
scope-manager/tests/eslint-scope/es6-default-parameters.test.ts:7
scope-manager/tests/eslint-scope/references.test.ts:450
scope-manager/tests/eslint-scope/references.test.ts:462
scope-manager/tests/eslint-scope/references.test.ts:484
scope-manager/tests/eslint-scope/references.test.ts:496
scope-manager/tests/eslint-scope/references.test.ts:520
scope-manager/tests/eslint-scope/references.test.ts:536
scope-manager/tests/fixtures.test.ts:174
typescript-eslint/tests/configs.test.ts:103
typescript-estree/src/convert.ts:553
typescript-estree/src/convert.ts:1047
typescript-estree/src/convert.ts:1083
typescript-estree/src/convert.ts:1647
typescript-estree/src/convert.ts:3206
typescript-estree/src/create-program/createProjectProgram.ts:65
typescript-estree/src/create-program/getWatchProgramsForProjects.ts:149
typescript-estree/src/create-program/getWatchProgramsForProjects.ts:410
typescript-estree/src/create-program/getWatchProgramsForProjects.ts:495
typescript-estree/src/node-utils.ts:679
typescript-estree/tests/lib/persistentParse.test.ts:32
typescript-estree/tests/lib/semanticInfo.test.ts:44
utils/src/eslint-utils/applyDefault.ts:25
website/src/components/editor/LoadedEditor.tsx:249
website/src/components/lib/createEventsBinder.ts:10
website/src/components/linter/bridge.ts:47
website/src/components/linter/bridge.ts:49
website/src/components/linter/createLinter.ts:67
website/src/components/linter/createLinter.ts:167
website/src/theme/prism-include-languages.js:10

no-array-method-this-argument (4 occurrences)

docs

Do not use the this argument in Array#findIndex().
website/plugins/generated-rule-docs/insertions/insertWhenNotToUseIt.ts:18

Do not use the this argument in Array#forEach().
scope-manager/src/referencer/PatternVisitor.ts:59
scope-manager/src/referencer/TypeVisitor.ts:191
scope-manager/src/referencer/Visitor.ts:40

no-array-push-push (22 occurrences)

docs

Do not call Array#push() multiple times.
ast-spec/tests/util/serializers/Node.ts:64
ast-spec/tests/util/serializers/Node.ts:76
ast-spec/tests/util/serializers/Node.ts:77
ast-spec/tests/util/serializers/Node.ts:87
eslint-plugin/src/rules/consistent-type-definitions.ts:61
eslint-plugin/src/rules/consistent-type-definitions.ts:96
eslint-plugin/src/rules/member-ordering.ts:578
eslint-plugin/src/rules/member-ordering.ts:582
eslint-plugin/src/rules/member-ordering.ts:594
eslint-plugin/src/rules/member-ordering.ts:598
eslint-plugin/src/rules/prefer-optional-chain-utils/gatherLogicalOperands.ts:341
eslint-plugin/tests/rules/no-unsafe-assignment.test.ts:33
eslint-plugin/tests/rules/semi.test.ts:274
eslint-plugin/tests/rules/semi.test.ts:1092
repo-tools/src/generate-contributors.mts:129
repo-tools/src/generate-contributors.mts:130
repo-tools/src/generate-contributors.mts:131
repo-tools/src/generate-contributors.mts:132
repo-tools/src/generate-contributors.mts:133
repo-tools/src/generate-contributors.mts:134
repo-tools/src/generate-contributors.mts:137
repo-tools/src/generate-lib.mts:281

no-array-reduce (29 occurrences)

docs

Array#reduce() is not allowed
eslint-plugin/src/rules/member-ordering.ts:317
eslint-plugin/src/rules/naming-convention-utils/parse-options.ts:85
eslint-plugin/src/rules/no-duplicate-type-constituents.ts:112
eslint-plugin/src/rules/no-type-alias.ts:328
eslint-plugin/src/rules/semi.ts:60
eslint-plugin/tests/configs.test.ts:20
eslint-plugin/tests/rules/func-call-spacing.test.ts:330
eslint-plugin/tests/rules/indent/indent.test.ts:596
eslint-plugin/tests/rules/no-base-to-string.test.ts:49
eslint-plugin/tests/rules/no-explicit-any.test.ts:1200
eslint-plugin/tests/rules/no-inferrable-types.test.ts:14
eslint-plugin/tests/rules/no-unsafe-assignment.test.ts:18
eslint-plugin/tests/rules/prefer-nullish-coalescing.test.ts:37
eslint-plugin/tests/rules/prefer-nullish-coalescing.test.ts:53
eslint-plugin/tests/rules/semi.test.ts:269
eslint-plugin/tests/rules/semi.test.ts:1082
eslint-plugin/tests/rules/type-annotation-spacing.test.ts:6567
eslint-plugin/tests/rules/type-annotation-spacing.test.ts:6609
parser/src/parser.ts:45
repo-tools/src/generate-configs.mts:75
repo-tools/src/generate-configs.mts:278
repo-tools/src/generate-configs.mts:396
repo-tools/src/generate-sponsors.mts:121
repo-tools/src/generate-sponsors.mts:132
typescript-eslint/tests/configs.test.ts:23
typescript-estree/src/parseSettings/resolveProjectList.ts:60
utils/src/eslint-utils/deepMerge.ts:25
website/src/components/config/ConfigTypeScript.tsx:35
website/src/components/lib/jsonSchema.ts:179

no-console-spaces (1 occurrence)

docs

Do not use trailing space between console.log parameters.
repo-tools/src/apply-canary-version.mts:35

no-for-loop (21 occurrences)

docs

Use a for-of loop instead of this for loop.
eslint-plugin/src/rules/no-unsafe-argument.ts:59
eslint-plugin/src/rules/prefer-includes.ts:82
eslint-plugin/src/rules/prefer-string-starts-ends-with.ts:139
eslint-plugin/tests/docs.test.ts:66
rule-schema-to-typescript-types/src/index.ts:33
scope-manager/tests/eslint-scope/es6-destructuring-assignments.test.ts:536
scope-manager/tests/eslint-scope/es6-destructuring-assignments.test.ts:543
scope-manager/tests/eslint-scope/es6-destructuring-assignments.test.ts:642
scope-manager/tests/eslint-scope/es6-destructuring-assignments.test.ts:656
scope-manager/tests/eslint-scope/es6-destructuring-assignments.test.ts:814
scope-manager/tests/eslint-scope/es6-destructuring-assignments.test.ts:950
scope-manager/tests/eslint-scope/es6-destructuring-assignments.test.ts:1099
scope-manager/tests/eslint-scope/es6-destructuring-assignments.test.ts:1127
scope-manager/tests/eslint-scope/es6-destructuring-assignments.test.ts:1140
scope-manager/tests/eslint-scope/es6-destructuring-assignments.test.ts:1169
scope-manager/tests/eslint-scope/es6-destructuring-assignments.test.ts:1183
scope-manager/tests/eslint-scope/es6-destructuring-assignments.test.ts:1212
scope-manager/tests/eslint-scope/es6-destructuring-assignments.test.ts:1229
type-utils/src/isUnsafeAssignment.ts:98
typescript-estree/src/node-utils.ts:780
website/src/components/ast/selectedRange.ts:53

no-hex-escape (10 occurrences)

docs

Use Unicode escapes instead of hexadecimal escapes.
repo-tools/src/generate-configs.mts:22
repo-tools/src/generate-configs.mts:22
repo-tools/src/generate-configs.mts:23
repo-tools/src/generate-configs.mts:23
repo-tools/src/generate-configs.mts:24
repo-tools/src/generate-configs.mts:24
repo-tools/src/generate-configs.mts:25
repo-tools/src/generate-configs.mts:25
repo-tools/src/generate-configs.mts:26
repo-tools/src/generate-configs.mts:26

no-lonely-if (24 occurrences)

docs

Unexpected if as the only statement in a if block without else.
eslint-plugin/src/rules/consistent-type-imports.ts:229
eslint-plugin/src/rules/consistent-type-imports.ts:559
eslint-plugin/src/rules/lines-around-comment.ts:403
eslint-plugin/src/rules/lines-around-comment.ts:407
eslint-plugin/src/rules/no-confusing-void-expression.ts:261
eslint-plugin/src/rules/no-confusing-void-expression.ts:273
eslint-plugin/src/rules/no-confusing-void-expression.ts:281
eslint-plugin/src/rules/no-confusing-void-expression.ts:291
eslint-plugin/src/rules/no-confusing-void-expression.ts:297
eslint-plugin/src/rules/no-confusing-void-expression.ts:300
eslint-plugin/src/rules/no-empty-interface.ts:62
eslint-plugin/src/rules/no-magic-numbers.ts:167
eslint-plugin/src/rules/no-misused-new.ts:102
eslint-plugin/src/rules/no-misused-promises.ts:513
eslint-plugin/src/rules/no-type-alias.ts:218
eslint-plugin/src/rules/no-unnecessary-parameter-property-assignment.ts:168
eslint-plugin/src/rules/prefer-optional-chain-utils/gatherLogicalOperands.ts:83
eslint-plugin/src/util/collectUnusedVariables.ts:284
eslint-plugin/src/util/getWrappingFixer.ts:64
rule-tester/src/utils/serialization.ts:34
typescript-estree/src/convert.ts:232
typescript-estree/src/convert.ts:3564
website/src/components/ast/selectedRange.ts:57
website/src/components/ast/tsUtils.ts:27

no-object-as-default-parameter (1 occurrence)

docs

Do not use an object literal as default for parameter options.
scope-manager/src/referencer/Visitor.ts:31

no-unused-properties (2 occurrences)

docs

Property emitDecoratorMetadata is defined but never used.
scope-manager/src/analyze.ts:75

Property lib is defined but never used.
scope-manager/src/analyze.ts:73

no-useless-spread (3 occurrences)

docs

Spread an object literal in object literal is unnecessary.
eslint-plugin/src/rules/naming-convention-utils/schema.ts:149
eslint-plugin/src/rules/type-annotation-spacing.ts:49
eslint-plugin/src/rules/type-annotation-spacing.ts:54

no-useless-switch-case (6 occurrences)

docs

Useless case in switch statement.
typescript-estree/src/convert.ts:651
typescript-estree/src/convert.ts:652
typescript-estree/src/node-utils.ts:591
typescript-estree/src/node-utils.ts:592
typescript-estree/src/node-utils.ts:593
typescript-estree/src/node-utils.ts:594

no-useless-undefined (17 occurrences)

docs

Do not use useless undefined.
eslint-plugin/src/rules/no-restricted-imports.ts:101
eslint-plugin/src/rules/no-restricted-imports.ts:109
eslint-plugin/src/rules/no-restricted-imports.ts:136
parser/tests/test-utils/test-utils.ts:25
typescript-estree/src/create-program/createIsolatedProgram.ts:54
typescript-estree/src/simple-traverse.ts:91
typescript-estree/tests/lib/createProjectService.test.ts:26
typescript-estree/tests/lib/createProjectService.test.ts:35
typescript-estree/tests/lib/createProjectService.test.ts:60
typescript-estree/tests/lib/createProjectService.test.ts:78
typescript-estree/tests/lib/createProjectService.test.ts:92
typescript-estree/tests/lib/createProjectService.test.ts:105
typescript-estree/tests/lib/useProgramFromProjectService.test.ts:211
website/src/components/ESQueryFilter.tsx:24
website/src/components/ast/DataRenderer.tsx:68
website/src/components/ast/DataRenderer.tsx:200
website/src/components/typeDetails/TypeInfo.tsx:71

number-literal-case (5 occurrences)

docs

Invalid number literal casing.
eslint-plugin/tests/rules/no-magic-numbers.test.ts:146
eslint-plugin/tests/rules/no-magic-numbers.test.ts:150
eslint-plugin/tests/rules/no-magic-numbers.test.ts:807
eslint-plugin/tests/rules/no-magic-numbers.test.ts:821
typescript-estree/src/node-utils.ts:457

prefer-add-event-listener (1 occurrence)

docs

Prefer addEventListener over onload.
website/src/components/editor/loadSandbox.ts:20

@abrahamguo abrahamguo added repo maintenance things to do with maintenance of the repo, and not with code/docs triage Waiting for team members to take a look labels Jul 23, 2024
@abrahamguo
Copy link
Contributor Author
10000 abrahamguo commented Jul 23, 2024
prefer-array-flat (1 occurrence)

docs

Prefer Array#flat() over Array#reduce() to flatten an array.
eslint-plugin/tests/rules/no-inferrable-types.test.ts:14

prefer-array-some (1 occurrence)

docs

Prefer .some(…) over .find(…).
eslint-plugin/src/rules/no-unnecessary-condition.ts:580

prefer-at (50 occurrences)

docs

Prefer .at(…) over [….length - index].
eslint-plugin-internal/src/rules/plugin-test-formatting.ts:300
eslint-plugin/src/rules/ban-ts-comment.ts:178
eslint-plugin/src/rules/class-literal-property-style.ts:135
eslint-plugin/src/rules/class-literal-property-style.ts:233
eslint-plugin/src/rules/comma-dangle.ts:113
eslint-plugin/src/rules/consistent-return.ts:54
eslint-plugin/src/rules/consistent-type-imports.ts:537
eslint-plugin/src/rules/consistent-type-imports.ts:552
eslint-plugin/src/rules/explicit-member-accessibility.ts:244
eslint-plugin/src/rules/explicit-module-boundary-types.ts:172
eslint-plugin/src/rules/member-delimiter-style.ts:326
eslint-plugin/src/rules/member-ordering.ts:698
eslint-plugin/src/rules/member-ordering.ts:825
eslint-plugin/src/rules/member-ordering.ts:845
eslint-plugin/src/rules/method-signature-style.ts:70
eslint-plugin/src/rules/no-confusing-void-expression.ts:261
eslint-plugin/src/rules/no-duplicate-type-constituents.ts:160
eslint-plugin/src/rules/no-duplicate-type-constituents.ts:173
eslint-plugin/src/rules/no-invalid-this.ts:86
eslint-plugin/src/rules/no-unsafe-argument.ts:118
eslint-plugin/src/rules/no-unsafe-argument.ts:123
eslint-plugin/src/rules/no-unused-vars.ts:161
eslint-plugin/src/rules/no-unused-vars.ts:422
eslint-plugin/src/rules/object-curly-spacing.ts:248
eslint-plugin/src/rules/padding-line-between-statements.ts:149
eslint-plugin/src/rules/parameter-properties.ts:141
eslint-plugin/src/rules/prefer-optional-chain-utils/analyzeChain.ts:213
eslint-plugin/src/rules/prefer-optional-chain-utils/analyzeChain.ts:511
eslint-plugin/src/rules/prefer-optional-chain-utils/analyzeChain.ts:567
eslint-plugin/src/rules/prefer-readonly.ts:234
eslint-plugin/src/rules/prefer-readonly.ts:246
eslint-plugin/src/rules/prefer-readonly.ts:250
eslint-plugin/src/rules/prefer-readonly.ts:261
eslint-plugin/src/rules/prefer-readonly.ts:263
eslint-plugin/src/rules/prefer-ts-expect-error.ts:41
eslint-plugin/src/rules/promise-function-async.ts:179
eslint-plugin/src/rules/switch-exhaustiveness-check.ts:198
eslint-plugin/src/rules/unified-signatures.ts:324
eslint-plugin/src/util/collectUnusedVariables.ts:657
eslint-plugin/src/util/getFunctionHeadLoc.ts:167
eslint-plugin/src/util/getMemberHeadLoc.ts:42
eslint-plugin/src/util/getMemberHeadLoc.ts:92
integration-tests/tools/pack-packages.ts:48
scope-manager/tests/eslint-scope/es6-default-parameters.test.ts:306
scope-manager/tests/eslint-scope/references.test.ts:456
scope-manager/tests/eslint-scope/references.test.ts:490
type-utils/src/isTypeReadonly.ts:153
type-utils/tests/TypeOrValueSpecifier.test.ts:142
typescript-estree/src/node-utils.ts:161

Prefer .at(…) over the first element from .slice(…).
eslint-plugin/src/util/misc.ts:181

prefer-code-point (2 occurrences)

docs

Prefer String#codePointAt() over String#charCodeAt().
type-utils/src/requiresQuoting.ts:11
type-utils/src/requiresQuoting.ts:16

prefer-dom-node-append (1 occurrence)

docs

Prefer Node#append() over Node#appendChild().
website/src/components/editor/loadSandbox.ts:47

prefer-export-from (6 occurrences)

docs

Use export…from to re-export ASTUtils.
utils/src/index.ts:7

Use export…from to re-export ConfigWithExtends.
typescript-eslint/src/index.ts:72

Use export…from to re-export ESLintUtils.
utils/src/index.ts:7

Use export…from to re-export JSONSchema.
utils/src/index.ts:7

Use export…from to re-export TSESLint.
utils/src/index.ts:7

Use export…from to re-export TSUtils.
utils/src/index.ts:7

prefer-includes (4 occurrences)

docs

Use .includes() instead of .some() when checking value existence.
eslint-plugin/src/rules/no-unnecessary-qualifier.ts:45
eslint-plugin/src/rules/padding-line-between-statements.ts:70
type-utils/src/TypeOrValueSpecifier.ts:126
type-utils/src/getTypeName.ts:57

prefer-math-trunc (4 occurrences)

docs

Use Math.trunc instead of << 0.
eslint-plugin/src/rules/naming-convention-utils/enums.ts:25
eslint-plugin/src/rules/naming-convention-utils/enums.ts:93
eslint-plugin/src/rules/prefer-regexp-exec.ts:17

Use Math.trunc instead of | 0.
website/src/components/linter/utils.ts:20

prefer-native-coercion-functions (2 occurrences)

docs

arrow function is equivalent to Boolean. Use Boolean directly.
typescript-estree/src/convert.ts:352
website/src/components/RulesTable/index.tsx:197

prefer-negative-index (1 occurrence)

docs

Prefer negative index over length minus index for at.
eslint-plugin/src/rules/no-unnecessary-parameter-property-assignment.ts:204

prefer-node-protocol (67 occurrences)

docs

Prefer node:child_process over child_process.
integration-tests/tools/pack-packages.ts:10
types/tools/copy-ast-spec.ts:1

Prefer node:fs over fs.
ast-spec/tests/fixtures.test.ts:1
eslint-plugin/tests/docs.test.ts:8
eslint-plugin/tests/index.test.ts:1
eslint-plugin/tests/rules/index.test.ts:1
integration-tests/tools/pack-packages.ts:11
parser/tests/lib/services.test.ts:2
repo-tools/src/generate-sponsors.mts:2
scope-manager/tests/fixtures.test.ts:1
types/tools/copy-ast-spec.ts:2
typescript-estree/src/create-program/getWatchProgramsForProjects.ts:2
typescript-estree/src/create-program/useProvidedPrograms.ts:2
typescript-estree/src/parseSettings/getProjectConfigFiles.ts:2
typescript-estree/tests/lib/persistentParse.test.ts:1
typescript-estree/tests/lib/semanticInfo.test.ts:1
website/plugins/generated-rule-docs/insertions/insertSpecialCaseOptions.ts:1
website/plugins/utils/rules.ts:6

Prefer node:os over os.
website/plugins/generated-rule-docs/insertions/insertNewRuleReferences.ts:4

Prefer node:path over path.
ast-spec/tests/fixtures.test.ts:4
eslint-plugin-internal/src/rules/no-relative-paths-to-internal-packages.ts:1
eslint-plugin-internal/tests/RuleTester.ts:1
eslint-plugin-internal/tests/rules/no-relative-paths-to-internal-packages.test.ts:2
eslint-plugin/src/rules/no-unnecessary-type-constraint.ts:3
eslint-plugin/tests/RuleTester.ts:5
eslint-plugin/tests/docs.test.ts:14
eslint-plugin/tests/index.test.ts:2
eslint-plugin/tests/rules/no-unnecessary-condition.test.ts:6
eslint-plugin/tests/rules/no-unnecessary-type-assertion.test.ts:2
eslint-plugin/tests/rules/prefer-nullish-coalescing.test.ts:3
eslint-plugin/tests/rules/strict-boolean-expressions.test.ts:4
eslint-plugin/tests/rules/switch-exhaustiveness-check.test.ts:2
integration-tests/tools/pack-packages.ts:12
parser/tests/lib/parser.test.ts:4
parser/tests/lib/services.test.ts:4
repo-tools/src/generate-sponsors.mts:3
scope-manager/tests/fixtures.test.ts:4
type-utils/src/TypeOrValueSpecifier.ts:3
type-utils/tests/TypeOrValueSpecifier.test.ts:4
type-utils/tests/getTypeName.test.ts:3
type-utils/tests/isSymbolFromDefaultLibrary.test.ts:3
type-utils/tests/isTypeReadonly.test.ts:3
type-utils/tests/isUnsafeAssignment.test.ts:3
type-utils/tests/typeFlagUtils.test.ts:3
types/tools/copy-ast-spec.ts:3
typescript-estree/src/create-program/createDefaultProgram.ts:2
typescript-estree/src/create-program/createProjectProgram.ts:2
typescript-estree/src/create-program/describeFilePath.ts:1
typescript-estree/src/create-program/getScriptKind.ts:1
typescript-estree/src/create-program/shared.ts:1
typescript-estree/src/create-program/useProvidedPrograms.ts:3
typescript-estree/src/parseSettings/getProjectConfigFiles.ts:3
typescript-estree/src/parseSettings/inferSingleRun.ts:1
typescript-estree/src/useProgramFromProjectService.ts:3
typescript-estree/tests/lib/getProjectConfigFiles.test.ts:1
typescript-estree/tests/lib/inferSingleRun.test.ts:1
typescript-estree/tests/lib/parse.project-true.test.ts:1
typescript-estree/tests/lib/parse.test.ts:4
typescript-estree/tests/lib/persistentParse.test.ts:2
typescript-estree/tests/lib/semanticInfo-singleRun.test.ts:2
typescript-estree/tests/lib/semanticInfo.test.ts:3
typescript-estree/tests/lib/useProgramFromProjectService.test.ts:2
website/plugins/generated-rule-docs/insertions/insertNewRuleReferences.ts:5
website/plugins/generated-rule-docs/insertions/insertSpecialCaseOptions.ts:3
website/plugins/utils/rules.ts:8
website/webpack.plugin.js:2

Prefer node:util over util.
types/tools/copy-ast-spec.ts:4

prefer-regexp-test (3 occurrences)

docs

Prefer .test(…) over .exec(…).
eslint-plugin/src/util/getWrappingFixer.ts:70
parser/tests/test-utils/test-utils.ts:62
typescript-estree/tests/test-utils/test-utils.ts:47

prefer-spread (48 occurrences)

docs

Prefer the spread operator over Array.from(…).
ast-spec/tests/fixtures.test.ts:341
ast-spec/tests/fixtures.test.ts:348
ast-spec/tests/fixtures.test.ts:358
ast-spec/tests/fixtures.test.ts:367
ast-spec/tests/util/serializers/Node.ts:24
eslint-plugin/src/rules/member-ordering.ts:302
eslint-plugin/src/rules/padding-line-between-statements.ts:47
eslint-plugin/src/rules/prefer-readonly.ts:461
eslint-plugin/src/rules/prefer-readonly.ts:462
eslint-plugin/src/rules/unified-signatures.ts:518
repo-tools/src/generate-lib.mts:240
repo-tools/src/generate-lib.mts:291
rule-schema-to-typescript-types/src/generateType.ts:39
rule-schema-to-typescript-types/src/optimizeAST.ts:47
scope-manager/src/ScopeManager.ts:59
scope-manager/tests/fixtures.test.ts:127
typescript-estree/src/create-program/createDefaultProgram.ts:30
typescript-estree/src/create-program/createProjectProgram.ts:51
typescript-estree/src/getModifiers.ts:20
typescript-estree/src/getModifiers.ts:47
typescript-estree/src/useProgramFromProjectService.ts:91
utils/src/eslint-utils/deepMerge.ts:25
website/src/components/config/ConfigTypeScript.tsx:53
website/src/components/editor/LoadedEditor.tsx:158
website/src/components/editor/useSandboxServices.ts:121
website/src/components/editor/useSandboxServices.ts:122
website/src/components/lib/jsonSchema.ts:190
website/src/components/lib/jsonSchema.ts:198
website/src/components/linter/createLinter.ts:185
website/src/components/linter/createParser.ts:30

Prefer the spread operator over Array#concat(…).
eslint-plugin/src/rules/consistent-type-exports.ts:293
eslint-plugin/src/rules/key-spacing.ts:417
eslint-plugin/src/rules/lines-around-comment.ts:159
eslint-plugin/src/rules/prefer-function-type.ts:113
eslint-plugin/tests/rules/no-inferrable-types.test.ts:14
eslint-plugin/tests/rules/type-annotation-spacing.test.ts:6569
eslint-plugin/tests/rules/type-annotation-spacing.test.ts:6611
rule-schema-to-typescript-types/src/printAST.ts:45
typescript-estree/src/convert.ts:1948
typescript-estree/src/convert.ts:2129
typescript-estree/src/create-program/getWatchProgramsForProjects.ts:338
typescript-estree/src/parseSettings/resolveProjectList.ts:98
typescript-estree/src/parseSettings/warnAboutTSVersion.ts:20
utils/src/eslint-utils/deepMerge.ts:23
website-eslint/src/mock/path.js:175

Prefer the spread operator over Array#slice().
eslint-plugin/src/rules/member-ordering.ts:508
eslint-plugin/src/rules/no-shadow.ts:651

Prefer the spread operator over String#split(``).
website/src/theme/NotFound/Content/index.tsx:16

prefer-string-replace-all (73 occurrences)

docs

Prefer String#replaceAll() over String#replace().
ast-spec/tests/fixtures.test.ts:78
eslint-plugin-internal/src/rules/plugin-test-formatting.ts:84
eslint-plugin-internal/src/rules/plugin-test-formatting.ts:85
eslint-plugin/src/rules/ban-types.ts:27
eslint-plugin/src/rules/enum-utils/shared.ts:92
eslint-plugin/src/rules/func-call-spacing.ts:111
eslint-plugin/src/rules/member-ordering.ts:708
eslint-plugin/src/rules/naming-convention-utils/shared.ts:10
eslint-plugin/src/rules/no-invalid-void-type.ts:106
eslint-plugin/src/rules/no-invalid-void-type.ts:110
eslint-plugin/src/rules/no-loss-of-precision.ts:39
eslint-plugin/src/rules/no-unnecessary-template-expression.ts:150
eslint-plugin/src/rules/no-useless-template-literals.ts:151
eslint-plugin/src/rules/prefer-includes.ts:139
eslint-plugin/src/util/escapeRegExp.ts:10
eslint-plugin/tests/docs.test.ts:242
eslint-plugin/tests/rules/indent/indent.test.ts:617
eslint-plugin/tests/rules/naming-convention/cases/createTestCases.ts:94
eslint-plugin/tests/rules/naming-convention/cases/createTestCases.ts:286
eslint-plugin/tests/rules/no-explicit-any.test.ts:1222
eslint-plugin/tests/rules/prefer-nullish-coalescing.test.ts:462
eslint-plugin/tests/rules/prefer-nullish-coalescing.test.ts:471
eslint-plugin/tests/rules/prefer-nullish-coalescing.test.ts:483
eslint-plugin/tests/rules/prefer-nullish-coalescing.test.ts:492
eslint-plugin/tests/rules/prefer-optional-chain/prefer-optional-chain.test.ts:1856
eslint-plugin/tests/rules/prefer-optional-chain/prefer-optional-chain.test.ts:1863
eslint-plugin/tests/rules/prefer-optional-chain/prefer-optional-chain.test.ts:1865
eslint-plugin/tests/rules/prefer-optional-chain/prefer-optional-chain.test.ts:1876
eslint-plugin/tests/rules/prefer-optional-chain/prefer-optional-chain.test.ts:1889
eslint-plugin/tests/rules/prefer-optional-chain/prefer-optional-chain.test.ts:1896
eslint-plugin/tests/rules/prefer-optional-chain/prefer-optional-chain.test.ts:1898
eslint-plugin/tests/rules/prefer-optional-chain/prefer-optional-chain.test.ts:1909
eslint-plugin/tests/rules/prefer-optional-chain/prefer-optional-chain.test.ts:1924
eslint-plugin/tests/rules/prefer-optional-chain/prefer-optional-chain.test.ts:1937
eslint-plugin/tests/rules/prefer-optional-chain/prefer-optional-chain.test.ts:1946
eslint-plugin/tests/rules/prefer-optional-chain/prefer-optional-chain.test.ts:1951
eslint-plugin/tests/rules/prefer-optional-chain/prefer-optional-chain.test.ts:1964
eslint-plugin/tests/rules/prefer-optional-chain/prefer-optional-chain.test.ts:1979
eslint-plugin/tests/rules/prefer-optional-chain/prefer-optional-chain.test.ts:1988
eslint-plugin/tests/rules/prefer-optional-chain/prefer-optional-chain.test.ts:1993
eslint-plugin/tests/rules/prefer-optional-chain/prefer-optional-chain.test.ts:2005
eslint-plugin/tests/rules/prefer-optional-chain/prefer-optional-chain.test.ts:2024
eslint-plugin/tests/rules/prefer-optional-chain/prefer-optional-chain.test.ts:2029
eslint-plugin/tests/rules/prefer-optional-chain/prefer-optional-chain.test.ts:2029
eslint-plugin/tests/rules/prefer-optional-chain/prefer-optional-chain.test.ts:2033
eslint-plugin/tests/rules/prefer-optional-chain/prefer-optional-chain.test.ts:2035
eslint-plugin/tests/rules/prefer-optional-chain/prefer-optional-chain.test.ts:2035
eslint-plugin/tests/rules/prefer-readonly-parameter-types.test.ts:482
eslint-plugin/tests/rules/prefer-readonly-parameter-types.test.ts:483
eslint-plugin/tests/rules/prefer-readonly-parameter-types.test.ts:484
eslint-plugin/tests/rules/prefer-readonly-parameter-types.test.ts:593
eslint-plugin/tests/rules/semi.test.ts:275
eslint-plugin/tests/rules/semi.test.ts:1084
eslint-plugin/tests/rules/semi.test.ts:1094
integration-tests/tools/integration-test-base.ts:169
repo-tools/src/generate-lib.mts:92
rule-schema-to-typescript-types/src/generateUnionType.ts:23
rule-tester/src/utils/config-validator.ts:55
rule-tester/src/utils/config-validator.ts:56
rule-tester/src/utils/validationHelpers.ts:64
types/tools/copy-ast-spec.ts:81
typescript-estree/src/convert.ts:2332
typescript-estree/src/node-utils.ts:450
typescript-estree/tests/lib/parse.test.ts:60
website-eslint/build.ts:14
website-eslint/build.ts:24
website-eslint/build.ts:24
website/src/components/editor/createProvideTwoslashInlay.ts:81
website/src/components/linter/utils.ts:182
website/src/components/linter/utils.ts:182
website/src/pages/index.tsx:115
website/src/pages/index.tsx:115
website/tools/generate-website-dts.ts:79

prefer-string-slice (7 occurrences)

docs

Prefer String#slice() over String#substring().
eslint-plugin-internal/src/rules/plugin-test-formatting.ts:393
eslint-plugin/src/rules/method-signature-style.ts:76
eslint-plugin/src/rules/prefer-optional-chain-utils/analyzeChain.ts:404
eslint-plugin/tools/generate-breaking-changes.mts:34
rule-schema-to-typescript-types/src/index.ts:90
website-eslint/src/mock/assert.js:59
website/src/components/ast/PropertyValue.tsx:23

prefer-switch (5 occurrences)

docs

Use switch instead of multiple else-if.
eslint-plugin/src/rules/explicit-module-boundary-types.ts:185
eslint-plugin/src/rules/no-floating-promises.ts:297
eslint-plugin/src/rules/no-type-alias.ts:262
eslint-plugin/src/rules/return-await.ts:194
eslint-plugin/src/util/getThisExpression.ts:8

prefer-ternary (17 occurrences)

docs

This if statement can be replaced by a ternary expression.
eslint-plugin/src/rules/class-methods-use-this.ts:114
eslint-plugin/src/rules/consistent-type-exports.ts:205
eslint-plugin/src/rules/consistent-type-exports.ts:224
eslint-plugin/src/rules/consistent-type-imports.ts:545
eslint-plugin/src/rules/consistent-type-imports.ts:734
eslint-plugin/src/rules/prefer-function-type.ts:126
eslint-plugin/src/rules/prefer-function-type.ts:164
eslint-plugin/src/rules/prefer-nullish-coalescing.ts:364
eslint-plugin/src/rules/prefer-optional-chain-utils/analyzeChain.ts:321
eslint-plugin/src/rules/prefer-readonly.ts:306
eslint-plugin/src/rules/prefer-string-starts-ends-with.ts:314
eslint-plugin/src/rules/return-await.ts:276
parser/src/parser.ts:92
rule-tester/src/utils/config-validator.ts:121
typescript-estree/src/convert.ts:1549
utils/src/eslint-utils/applyDefault.ts:29
utils/src/eslint-utils/deepMerge.ts:32

prefer-top-level-await (10 occurrences)

docs

Prefer top-level await over an async IIFE.
repo-tools/src/postinstall.mts:31
website/plugins/generated-rule-docs/insertions/insertNewRuleReferences.ts:40

Prefer top-level await over using a promise chain.
eslint-plugin/tools/generate-breaking-changes.mts:159
repo-tools/src/generate-configs.mts:410
repo-tools/src/generate-contributors.mts:174
repo-tools/src/generate-lib.mts:310
repo-tools/src/generate-sponsors.mts:192
types/tools/copy-ast-spec.ts:86
website-eslint/build.ts:166
website/tools/generate-website-dts.ts:105

prefer-type-error (10 occurrences)

docs

new Error() is too unspecific for a type check. Use new TypeError() instead.
repo-tools/src/generate-contributors.mts:64
rule-tester/src/TestFramework.ts:112
rule-tester/src/TestFramework.ts:117
rule-tester/src/TestFramework.ts:167
rule-tester/src/TestFramework.ts:173
rule-tester/src/TestFramework.ts:205
rule-tester/src/TestFramework.ts:210
rule-tester/src/utils/config-validator.ts:122
rule-tester/src/utils/config-validator.ts:124
scope-manager/tests/fixtures.test.ts:103

text-encoding-identifier-case (6 occurrences)

docs

Prefer utf8 over utf-8.
eslint-plugin/tests/docs.test.ts:31
eslint-plugin/tests/docs.test.ts:537
integration-tests/tools/pack-packages.ts:45
types/tools/copy-ast-spec.ts:54
types/tools/copy-ast-spec.ts:61
typescript-estree/src/create-program/useProvidedPrograms.ts:77

@Josh-Cena
Copy link
Member
Josh-Cena commented Jul 23, 2024

I'm not familiar with eslint-plugin-unicorn so it took me slightly longer to look at some of the rules (in fact I'm surprised we have this plugin at all).

Tentatively, I'm +1 on (as in, I believe this coding style will benefit us):

  • catch-error-name (but we should either use e or err, not error—I actively hate full names)
  • custom-error-definition
  • error-message
  • no-console-spaces
  • no-for-loop (why isn't this caught by our prefer-for-of?)
  • no-useless-spread
  • prefer-add-event-listener
  • prefer-array-flat
  • prefer-array-some
  • prefer-at
  • prefer-code-point
  • prefer-dom-node-append
  • prefer-includes
  • prefer-math-trunc
  • prefer-negative-index
  • prefer-node-protocol
  • prefer-regexp-test
  • prefer-top-level-await
  • text-encoding-identifier-case

I'm +0/-0.5 on (as in, I believe this coding style is desirable, but it's either not useful or may take away some expressiveness unnecessarily):

  • better-regex (I'm a big fan of regexes and I think we should lint them with eslint-plugin-regexp (which I use a lot), which should be able to provide the same capabilities.)
  • no-array-push-push
  • no-lonely-if
  • no-unused-properties (not sure how reliable it is)
  • prefer-export-from
  • prefer-native-coercion-functions (this is a funny one because Boolean is not a predicate, but I'm open to testing because it looks like they aren't used as predicates anyway.)
  • prefer-spread
  • prefer-string-replace-all
  • prefer-string-slice
  • prefer-switch
  • prefer-ternary
  • prefer-type-error

I'm -1 on (as in, this actively goes against my coding preferences or may not work with other tools):

  • no-array-for-each
  • no-array-method-this-argument
  • no-array-reduce
  • no-hex-escape
  • no-object-as-default-parameter
  • no-useless-switch-case
  • no-useless-undefined
  • number-literal-case (this probably conflicts with Prettier, and is best useless)

@sindresorhus
Copy link

no-array-for-each

There are many benefit with for-of loops: https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-array-for-each.md

no-object-as-default-parameter

This one is catching actual mistakes: https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-object-as-default-parameter.md

@Josh-Cena
Copy link
Member

no-array-for-each

I would prefer to leave this discretion to the author. The performance is not a concern in our case; readability is debatable, especially when the array expression is long; ability to skip iterations is also present with forEach, so the only real benefit seems to be ability to exit early, but that's rarely needed, if you look at the places it's reporting on.

no-object-as-default-parameter

The only place it's reporting on has only one property, if the rule's only motivation is "default options with more than one option". And in general I don't think that's a bug vector, since the type information would accurately tell us what each property can and cannot be.

@abrahamguo
Copy link
Contributor Author

@Josh-Cena another benefit of prefer-for-each that might be more relevant for us:

Additionally, using for…of has great benefits if you are using TypeScript, because it does not cause a function boundary to be crossed. This means that type-narrowing earlier on in the current scope will work properly while inside of the loop (without having to re-type-narrow). Furthermore, any mutated variables inside of the loop will picked up on for the purposes of determining if a variable is being used.

@abrahamguo
Copy link
Contributor Author

no-object-as-default-parameter

The only place it's reporting on has only one property

That's actually not correct; that file has

 options: VisitPatternOptions = { processRightHandNodes: false },

and earlier in that same file,

interface VisitPatternOptions extends PatternVisitorOptions {
  processRightHandNodes?: boolean;
}

and following the chain of interfaces, there are actually two more options:

interface VisitorOptions {
  childVisitorKeys?: VisitorKeys | null;
  visitChildrenEvenIfSelectorExists?: boolean;
}

@Josh-Cena
Copy link
Member
Josh-Cena commented Jul 23, 2024

I agree for...of loops have many benefits and I'm not against using it, but I don't think it's worthwhile to crystalize it in a rule.

Apologies, I misread the motivation for the no-object-as-default-parameter rule. This rule also prevents the case where someone passes an empty object and overrides the default which has one property. Still my point stands: this property is already typed to be nullable, so it doesn't matter if it's guaranteed to be present at runtime, since we have to write code to guard against this case anyway. If we change the type definition then TS will force the callsites to change too. I don't find it useful in a fully typed codebase.

@JoshuaKGoldberg
Copy link
Member

(but we should either use e or err, not error—I actively hate full names)

I actively hate abbreviations and think we should use error, not e or err. 😂

I think we should lint them with eslint-plugin-regexp (which I use a lot), which should be able to provide the same capabilities

Strong +1. Potentially hot take (someone please yell at me if it's not good): any universally useful rules from eslint-plugin-unicorn that don't exist in eslint-plugin-regexp should IMO be filed as feature requests on eslint-plugin-regexp. IMO there's no need to have them in a catch-all general community plugin when a standard plugin for regexps exists.

@abrahamguo
Copy link
Contributor Author

@JoshuaKGoldberg makes sense! and yes, the functionality from unicorn's one regexp rule can all be done by eslint-plugin-regexp.

@abrahamguo
Copy link
Contributor Author
abrahamguo commented Jul 23, 2024

Responding to a few of @Josh-Cena's thoughts from earlier:

  • no-unused-properties (not sure how reliable it is)

At a quick glance at some of the reports, they certainly look correct. I use this rule at work and have not had any false positives from it. I'm guessing the rule is pretty conservative and bails out right away if the whole object is used somewhere.

  • prefer-native-coercion-functions (this is a funny one because Boolean is not a predicate, but I'm open to testing because it looks like they aren't used as predicates anyway.)

Yeah, inferred filter predicates just landed in TypeScript anyways, and you have to write your callbacks in very specific ways in order to use the inferred predicate feature. But certainly worth looking whether using real TypeScript predicates would be beneficial.

  • no-array-method-this-argument

Three of those reports are understable to keep that way. However, this one is certainly a mistake:

Do not use the this argument in Array#findIndex().

website/plugins/generated-rule-docs/insertions/insertWhenNotToUseIt.ts:18

  • no-array-reduce

Note that this rule does allow using reduce for array summations. I will want to look at the specific reports, because in at least some of them, it does seem like there is a more idiomatic method to use.

@Josh-Cena
Copy link
Member

However, this one is certainly a mistake:

I'm surprised and I don't even remember what it's supposed to look like!

I will want to look at the specific reports, because in at least some of them, it does seem like there is a more idiomatic method to use.

Sounds good 👍 I'm also pro-remove-reduce, but want to allow the freedom in case it is useful.

@kirkwaiblinger
Copy link
Member
kirkwaiblinger commented Jul 24, 2024

@abrahamguo Just wanna say real quick I really like how neatly you've created the issue report and included the links and everything. Super helpful ❤️

I'll preface all of the following with saying that I haven't personally used any of these rules, so my opinions are only as good as my understanding of the rule's intent, my ignorance as to edge cases, and the limited amount of time I've spent thinking about each one....

rule score words
better-regex +/- 0 others seem to know more
catch-error-name +1 I significantly prefer unabbreviated error too
custom-error-definition +1? I don't understand this well, but it seems sensible. This report does seem like a false positive/bug in the rule though 🤔
error-message +0.5 The one report is a special case we'd want to disable, but the rule seems reasonable
no-array-for-each +1.5 I am a die-hard True Believer in for...of. I'll spare the manifesto for now, but I'll mention that I mostly disagree with the assessment in #9629 (comment); just use an intermediate variable.
no-array-method-this-argument +1
no-array-push-push -1 just not a fan
no-array-reduce -0.5 Checked a few of the report examples, and they were heinous IMO. However, I think this is a concern that is the domain of human code review, not linting
no-console-spaces +0.5
no-for-loop +0.5 I like. But it's pretty opinionated.
no-hex-escape +0.5? I have no prior knowledge of this, but the rule description sounds sensible
no-lonely-if -1 (edited) how is this different from the eslint core rule? This rule is even worse than the core rule. Booooo
no-object-as-default-parameter +0.1 description sounds plausible, but haven't thought about this hard
no-unused-properties -0.5? This seems not useful when using TS. Note that the rule description even says, (paraphrasing) to overcome to the limitations of this rule, use TS.
no-useless-spread +1
no-useless-switch-case -0.1 It's useful to be explicit sometimes.... A glance at the reports didn't seem too suspicious.
no-useless-undefined -100 Actively, strongly disagree with the premise of this rule (particularly in the context of TS)
number-literal-case -1 (edited) Does other tooling (i.e. prettier) already handle this? Conflicts with other tooling
prefer-add-event-listener +0.5?
prefer-array-flat +1
prefer-array-some -0.5? See also #8378 🤔
prefer-at -0.5? See also #6401 🤔
prefer-code-point +/- 0 can't be bothered to read up on this one
prefer-dom-node-append +/-0 🤷
prefer-export-from +0.5
prefer-includes -1 we should be dogfooding https://typescript-eslint.io/rules/prefer-includes/ instead
prefer-math-trunc +0.5 3/4 cases are 1 << 0 in a flags enum, which should stay as-is. The remaining 1 case looks like an actual bug
prefer-native-coercion-functions +/-0 don't have the attention span to think hard about this one right now, but I'm wary of it (and no-implicit-coercion is my main concern anyway)
prefer-negative-index -1? related to prefer-at, see #6401 🤔
prefer-node-protocol +0.1
prefer-regexp-test +0.1
prefer-spread +0.5
prefer-string-replace-all +0.1
prefer-string-slice +0.5
prefer-switch -1
prefer-ternary -0.5
prefer-top-level-await +1 This one is quite intriguing to me, and may be helpful to keep in mind for users with pains around no-floating-promises
prefer-type-error -0.5 This feels like a JS practice for validation that we avoid having to do in TS due to the type system, but I could be wrong
text-encoding-identifier-case +/-0? does TS type system itself not enforce/encourage this?

EDIT - Added second batch of rules

@Josh-Cena
Copy link
Member

just use an intermediate variable.

Needless to say my biggest principle is concise code, so "no" to full names, "no" to redundant braces, and "no" to intermediate variables, but I can see how I'm in the minority especially among linter maintainers :P

how is this different from the eslint core rule?

The core rule only reports on else { if {} }. This one reports on if { if {} }, which I personally think is fine.

Does other tooling (i.e. prettier) already handle this?

Yes.

@kirkwaiblinger
Copy link
Member

Needless to say my biggest principle is concise code, so "no" to full names, "no" to redundant braces, and "no" to intermediate variables, but I can see how I'm in the minority especially among linter maintainers :P

Most concise != least entropy 😁

how is this different from the eslint core rule?

The core rule only reports on else { if {} }. This one reports on if { if {} }, which I personally think is fine.

Gotcha. I'm -1 on both 👍

Does other tooling (i.e. prettier) already handle this?

Yes.

Cool, sounds like we should omit it then 👍

@kirkwaiblinger
Copy link
Member

Throwing this out there, I think we should automatically reject adding any rule from unicorn that has a near-identical form in typescript-eslint, or has a proposal in typescript-eslint that is "accepting PRs".

If it exists in our plugin, we should use it, and if it's inadequate, we should fix it.

If it doesn't yet exist, but we have accepted it, it either means

  • We're aware of the unicorn version, but believe that it's lacking in functionality without type information for some reason.
  • Or, we weren't aware of the unicorn version. In that case, and if it's adequate without type information, then we should close/"wontfix" the proposal in typescript-eslint, and use the unicorn version. Otherwise, we should just dogfood our own version once it's released.

I've noted one or two rules with near-identical forms or proposals thereof in typescript-eslint, but there may be more. Let's be sure to double check before proceeding with the unicorn rules.

@meszaros-lajos-gyorgy

This comment was marked as off-topic.

This comment was marked as off-topic.

@JoshuaKGoldberg
Copy link
Member

@meszaros-lajos-gyorgy you're right: that is off topic and not what this issue is about 🙂. https://typescript-eslint.io/contributing/issues#questions-and-support-requests has links to places you can ask for help.

@fisker
Copy link
Contributor
fisker commented Jul 27, 2024

No one likes prefer-string-raw?

@Josh-Cena
Copy link
Member

It depends. String.raw is 10 characters long so the rule is only beneficial if there are more than 10 backslashes in the string.

@bradzacher
Copy link
Member
bradzacher commented Jul 27, 2024

so the rule is only beneficial if there are more than 10 backslashes in the string

I don't think the point of String.raw is conciseness 😅
It's about readability - you don't need to think about escaping backslashes so it's easier to read and understand such strings.

eg "C:\\windows\\style\\path\\to\\file.js" is less clear than String.raw`C:\windows\style\path\to\file.js`

@Josh-Cena
Copy link
Member
Josh-Cena commented Jul 27, 2024

I find them equally readable, FWIW, especially with proper syntax highlighting that tells you what is escaped and what is not. I'm not strongly opposed to this rule though.

@bradzacher
Copy link
Member
rule score words
better-regex +1
catch-error-name -1 I personally dislike restrictions on names -- I think that they are bikeshedding stylistic rules that don't actually improve readability
custom-error-definition +1
error-message 0 I don't think it actually will catch a bug for us
no-array-for-each 0 I'm in favour of "standardising the codebase", but our codebase has about 50/50 forEach vs for..of. IDK I guess we could standardise on for..of?
no-array-method-this-argument +1
no-array-push-push -1e9999 Many of the reports I very purposely wrote like that because it causes the code to be laid out in an easy to read fashion. I don't think this nitpick is valuable, personally -- seems weird to be in their recommended set.
no-array-reduce -1e9999 reduce has its uses and banning it outright isn't good. I'm gobsmacked that such an opinionated rule is in the recommended set.
no-console-spaces +1
no-for-loop -1 The idea is great but the implementation seems wrong. For example this loop uses its i for things other than array index, or both this loop and this loop uses the i for accessing two different arrays at once.
no-hex-escape -1 IDK if one is clearer than the other, IMO. And the one case it's reporting on is clearer with hex codes cos it's console colour escapes.
no-lonely-if +1
no-object-as-default-parameter 0 Sure I guess but IDC either way
no-unused-properties +1
no-useless-spread +1
no-useless-switch-case -1e9999 I prefer being explicitly exhaustive and listing conditions out to make it clear that they were considered and handled as opposed to leaving it implicit.
no-useless-undefined -1 I don't think this makes code any better - an explicit undefined can make code easier to understand
number-literal-case 0 I don't think this makes anything clearer, personally but whatever
prefer-add-event-listener 0 We're not a webapp mostly and we don't use event listeners - I don't think it's worth turning on
prefer-array-flat +0.5
prefer-array-some 0 Meh IDC
prefer-at +1
prefer-code-point -1 Just cos the only reports are from code that was synced from TS
prefer-dom-node-append 0 Ditto for add event listener
prefer-export-from +0.5
prefer-includes +1
prefer-math-trunc -1 cos it's flagging << 0 which we commonly use in flag enums for the first member
prefer-native-coercion-functions +1
prefer-negative-index +1
prefer-node-protocol +1
prefer-regexp-test +1
prefer-spread -1 I don't think that [...x] is clearer or better than Array.from(x)
prefer-string-replace-all +1
prefer-string-slice 0 Almost a -1 just cos of the rule's description "String#substr() and String#substring() are the two lesser known legacy ways to slice a string" -- like "lesser known"? WHAT?
prefer-switch -1 I don't think a switch is always the better construct -- I think that an if/else can make code clearer sometimes.
prefer-ternary -1 I don't think conciseness is better or clearer. And looking at some of those reports it would actively harm the code clarity.
prefer-top-level-await -♾ We don't use MJS so we can't use TLA always. Also this case should NOT use TLA because the await is in a nested scope. So the rule is wrong.
prefer-type-error -1e9999 It's misclassifying many of our conditions as "type check conditions". So it's just wrong?
text-encoding-identifier-case +1

@Josh-Cena
Copy link
Member

better-regex +1

This rule may become deprecated and is certainly buggy: sindresorhus/eslint-plugin-unicorn#2409 and better alternatives exist (as proposed above), so I hope you are not too married to it.

no-array-reduce -1e9999

Could you give a valid reduce use case that cannot, or should not, be refactored to a for...of loop for better performance and readability? This would be helpful to be added to the MDN docs too, since I scratched my head to come up with two (2) valid use cases: summation (and other related operations), function piping (and its async version).

no-for-loop -1

The suggestion is to use entries(). I don't have strong opinions but I slightly prefer C-style for loops.

prefer-add-event-listener 0

We have a web app: the website.

@fisker
Copy link
Contributor
fisker commented Jul 27, 2024

Also this case should NOT use TLA because the await is in a nested scope. So the rule is wrong.

You misunderstood, it reports not because there is an await, but because prettierConfig is a Promise

@bradzacher
Copy link
Member
bradzacher commented Jul 27, 2024

We have a web app: the website.

Sure but it's react - so we don't delve into the imperative APIs much. And it's also minimal amounts of code. Hence "pretty low value for our codebase".

The suggestion is to use entries().

I don't see how

for (const [i, paramA] of Object.entries(paramsA)) {
  const paramB = paramsB[i]; 

Is in any way clearer than

for (let i = 0; i < paramsA.length; ++i) {
  const paramA = paramsA[i];
  const paramB = paramsB[i]; 

It's worse in every way, IMO.

So will update my vote to -1e9999

Could you give a valid reduce use case that cannot, or should not, be refactored to a for...of loop for better performance and readability?

It's an opinionated stylistic thing to choose one over the other. In your opinion a for loop is more readable.

For example I disagree that

const result = {} as ParsedOptions;
for (const k of getEnumNames(Selectors)) {
  result[k] = createValidator(k, context, normalizedOptions); 
}

Is necessarily clearer than

const result = getEnumNames(Selectors).reduce((acc, k) => {
  acc[k] = createValidator(k, context, normalizedOptions);
  return acc;
}, {} as ParsedOptions);

Being functional, reduce promotes isolation and encapsulation - it makes you think "I don't want to mutate values outside of the loop closure" - which is good for minimising side-effects of the loop and making code more predictable.

But the for..of version is made to explicitly mutate a value outside the loop closure. It purposely invites you to add side-effects to loops.

I'm firmly against this rule. I understand some people don't like reduce - but it's ultimately an opinionated, stylistic choice to use one over the other.
Some people are very loudly and vehemently against using enums but that doesn't mean they're right or that everyone should migrate off of them. I see this as the same class of opinionated, stylistic debate that codebases can choose to lint for if they want.

better-regex +1
This rule may become deprecated

🤷‍♂️ I didn't look into it too much. I noticed you guys were discussing it above. I was just weighing in that I'm good with the idea of linting to improve our regex.

@alfaproject
Copy link

I accidentally stumbled upon this thread while checking the stylistic typed recommended rules. We also use unicorn and some of the rules look nearly identical but in the documentation they are not mentioned so it's not obvious to me whether I should keep using the unicorn ones that look identical since they don't need types, or I should instead prefer the ones from here.

I see above that there is awareness of the overlap, but have you considered adding to the docs why the ones in this repo are better (nor not) than the ones from unicorn?

@bradzacher
Copy link
Member

Often times the overlap is that the two projects grew independently and there weren't open lines of communication to keep track of what each other was working on.

Sometimes it because we offered a type-aware version (more correct but slower and limited to TS codebases) and they chose a pure-syntactic version (faster, chance of false positives, applies to non-TS codebases).

Which rules are you talking about specifically?

@alfaproject
Copy link

Some examples:

There's probably more, I only had a quick look at the stylish ones like I mentioned.

I understand that both projects grow independently but I was just wondering if it would be helpful to add in the documentation like you do for base eslint rules, something like, if you enable this rule, please bear in mind that it might conflict with this other rule from unicorn (or some other popular plugin).

In terms of documentation I've seen other plugin authors doing the same for popular plugins which I think unicorn qualifies. This can be done by the community ofc if that's desired. For instance in this plugin: https://github.com/lydell/eslint-plugin-simple-import-sort

Make sure not to use other sorting rules at the same time:

@JoshuaKGoldberg
Copy link
Member

@abrahamguo were there any other rules you wanted to enable here? Just checking before we close this out. 🙂

@abrahamguo
Copy link
Contributor Author

Should be good to close!

@github-actions github-actions bot added the locked due to age Please open a new issue if you'd like to say more. See https://typescript-eslint.io/contributing. label Oct 26, 2024
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Oct 26, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
accepting prs Go ahead, send a pull request that resolves this issue locked due to age Please open a new issue if you'd like to say more. See https://typescript-eslint.io/contributing. repo maintenance things to do with maintenance of the repo, and not with code/docs
Projects
None yet
Development

Successfully merging a pull request may close this issue.

9 participants
0