@depup/typescript-eslint__eslint-plugin 8.57.1-depup.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +25 -0
- package/changes.json +5 -0
- package/dist/configs/eslint-recommended-raw.d.ts +10 -0
- package/dist/configs/eslint-recommended-raw.js +46 -0
- package/dist/configs/eslintrc/all.d.ts +159 -0
- package/dist/configs/eslintrc/all.js +165 -0
- package/dist/configs/eslintrc/base.d.ts +8 -0
- package/dist/configs/eslintrc/base.js +6 -0
- package/dist/configs/eslintrc/disable-type-checked.d.ts +71 -0
- package/dist/configs/eslintrc/disable-type-checked.js +73 -0
- package/dist/configs/eslintrc/eslint-recommended.d.ts +12 -0
- package/dist/configs/eslintrc/eslint-recommended.js +13 -0
- package/dist/configs/eslintrc/recommended-type-checked-only.d.ts +33 -0
- package/dist/configs/eslintrc/recommended-type-checked-only.js +39 -0
- package/dist/configs/eslintrc/recommended-type-checked.d.ts +56 -0
- package/dist/configs/eslintrc/recommended-type-checked.js +62 -0
- package/dist/configs/eslintrc/recommended.d.ts +29 -0
- package/dist/configs/eslintrc/recommended.js +35 -0
- package/dist/configs/eslintrc/strict-type-checked-only.d.ts +64 -0
- package/dist/configs/eslintrc/strict-type-checked-only.js +79 -0
- package/dist/configs/eslintrc/strict-type-checked.d.ts +98 -0
- package/dist/configs/eslintrc/strict-type-checked.js +114 -0
- package/dist/configs/eslintrc/strict.d.ts +40 -0
- package/dist/configs/eslintrc/strict.js +47 -0
- package/dist/configs/eslintrc/stylistic-type-checked-only.d.ts +15 -0
- package/dist/configs/eslintrc/stylistic-type-checked-only.js +21 -0
- package/dist/configs/eslintrc/stylistic-type-checked.d.ts +29 -0
- package/dist/configs/eslintrc/stylistic-type-checked.js +35 -0
- package/dist/configs/eslintrc/stylistic.d.ts +20 -0
- package/dist/configs/eslintrc/stylistic.js +26 -0
- package/dist/configs/flat/all.d.ts +7 -0
- package/dist/configs/flat/all.js +179 -0
- package/dist/configs/flat/base.d.ts +8 -0
- package/dist/configs/flat/base.js +17 -0
- package/dist/configs/flat/disable-type-checked.d.ts +7 -0
- package/dist/configs/flat/disable-type-checked.js +81 -0
- package/dist/configs/flat/eslint-recommended.d.ts +9 -0
- package/dist/configs/flat/eslint-recommended.js +16 -0
- package/dist/configs/flat/recommended-type-checked-only.d.ts +7 -0
- package/dist/configs/flat/recommended-type-checked-only.js +53 -0
- package/dist/configs/flat/recommended-type-checked.d.ts +7 -0
- package/dist/configs/flat/recommended-type-checked.js +76 -0
- package/dist/configs/flat/recommended.d.ts +7 -0
- package/dist/configs/flat/recommended.js +49 -0
- package/dist/configs/flat/strict-type-checked-only.d.ts +7 -0
- package/dist/configs/flat/strict-type-checked-only.js +93 -0
- package/dist/configs/flat/strict-type-checked.d.ts +7 -0
- package/dist/configs/flat/strict-type-checked.js +128 -0
- package/dist/configs/flat/strict.d.ts +7 -0
- package/dist/configs/flat/strict.js +61 -0
- package/dist/configs/flat/stylistic-type-checked-only.d.ts +7 -0
- package/dist/configs/flat/stylistic-type-checked-only.js +35 -0
- package/dist/configs/flat/stylistic-type-checked.d.ts +7 -0
- package/dist/configs/flat/stylistic-type-checked.js +49 -0
- package/dist/configs/flat/stylistic.d.ts +7 -0
- package/dist/configs/flat/stylistic.js +40 -0
- package/dist/index.d.ts +1128 -0
- package/dist/index.js +6 -0
- package/dist/raw-plugin.d.ts +1152 -0
- package/dist/raw-plugin.js +122 -0
- package/dist/rules/adjacent-overload-signatures.d.ts +4 -0
- package/dist/rules/adjacent-overload-signatures.js +124 -0
- package/dist/rules/array-type.d.ts +12 -0
- package/dist/rules/array-type.js +232 -0
- package/dist/rules/await-thenable.d.ts +6 -0
- package/dist/rules/await-thenable.js +228 -0
- package/dist/rules/ban-ts-comment.d.ts +17 -0
- package/dist/rules/ban-ts-comment.js +195 -0
- package/dist/rules/ban-tslint-comment.d.ts +4 -0
- package/dist/rules/ban-tslint-comment.js +53 -0
- package/dist/rules/class-literal-property-style.d.ts +7 -0
- package/dist/rules/class-literal-property-style.js +160 -0
- package/dist/rules/class-methods-use-this.d.ts +13 -0
- package/dist/rules/class-methods-use-this.js +219 -0
- package/dist/rules/consistent-generic-constructors.d.ts +6 -0
- package/dist/rules/consistent-generic-constructors.js +126 -0
- package/dist/rules/consistent-indexed-object-style.d.ts +7 -0
- package/dist/rules/consistent-indexed-object-style.js +256 -0
- package/dist/rules/consistent-return.d.ts +18 -0
- package/dist/rules/consistent-return.js +135 -0
- package/dist/rules/consistent-type-assertions.d.ts +14 -0
- package/dist/rules/consistent-type-assertions.js +256 -0
- package/dist/rules/consistent-type-definitions.d.ts +5 -0
- package/dist/rules/consistent-type-definitions.js +100 -0
- package/dist/rules/consistent-type-exports.d.ts +11 -0
- package/dist/rules/consistent-type-exports.js +335 -0
- package/dist/rules/consistent-type-imports.d.ts +15 -0
- package/dist/rules/consistent-type-imports.js +608 -0
- package/dist/rules/default-param-last.d.ts +4 -0
- package/dist/rules/default-param-last.js +68 -0
- package/dist/rules/dot-notation.d.ts +23 -0
- package/dist/rules/dot-notation.js +139 -0
- package/dist/rules/enum-utils/shared.d.ts +36 -0
- package/dist/rules/enum-utils/shared.js +121 -0
- package/dist/rules/explicit-function-return-type.d.ts +17 -0
- package/dist/rules/explicit-function-return-type.js +179 -0
- package/dist/rules/explicit-member-accessibility.d.ts +19 -0
- package/dist/rules/explicit-member-accessibility.js +299 -0
- package/dist/rules/explicit-module-boundary-types.d.ts +15 -0
- package/dist/rules/explicit-module-boundary-types.js +386 -0
- package/dist/rules/index.d.ts +448 -0
- package/dist/rules/index.js +275 -0
- package/dist/rules/init-declarations.d.ts +15 -0
- package/dist/rules/init-declarations.js +105 -0
- package/dist/rules/max-params.d.ts +25 -0
- package/dist/rules/max-params.js +72 -0
- package/dist/rules/member-ordering.d.ts +33 -0
- package/dist/rules/member-ordering.js +833 -0
- package/dist/rules/method-signature-style.d.ts +6 -0
- package/dist/rules/method-signature-style.js +186 -0
- package/dist/rules/naming-convention-utils/enums.d.ts +79 -0
- package/dist/rules/naming-convention-utils/enums.js +102 -0
- package/dist/rules/naming-convention-utils/format.d.ts +2 -0
- package/dist/rules/naming-convention-utils/format.js +89 -0
- package/dist/rules/naming-convention-utils/index.d.ts +6 -0
- package/dist/rules/naming-convention-utils/index.js +11 -0
- package/dist/rules/naming-convention-utils/parse-options.d.ts +2 -0
- package/dist/rules/naming-convention-utils/parse-options.js +69 -0
- package/dist/rules/naming-convention-utils/schema.d.ts +2 -0
- package/dist/rules/naming-convention-utils/schema.js +305 -0
- package/dist/rules/naming-convention-utils/shared.d.ts +5 -0
- package/dist/rules/naming-convention-utils/shared.js +16 -0
- package/dist/rules/naming-convention-utils/types.d.ts +39 -0
- package/dist/rules/naming-convention-utils/types.js +2 -0
- package/dist/rules/naming-convention-utils/validator.d.ts +3 -0
- package/dist/rules/naming-convention-utils/validator.js +349 -0
- package/dist/rules/naming-convention.d.ts +8 -0
- package/dist/rules/naming-convention.js +505 -0
- package/dist/rules/no-array-constructor.d.ts +4 -0
- package/dist/rules/no-array-constructor.js +62 -0
- package/dist/rules/no-array-delete.d.ts +6 -0
- package/dist/rules/no-array-delete.js +80 -0
- package/dist/rules/no-base-to-string.d.ts +11 -0
- package/dist/rules/no-base-to-string.js +324 -0
- package/dist/rules/no-confusing-non-null-assertion.d.ts +6 -0
- package/dist/rules/no-confusing-non-null-assertion.js +142 -0
- package/dist/rules/no-confusing-void-expression.d.ts +13 -0
- package/dist/rules/no-confusing-void-expression.js +357 -0
- package/dist/rules/no-deprecated.d.ts +11 -0
- package/dist/rules/no-deprecated.js +402 -0
- package/dist/rules/no-dupe-class-members.d.ts +14 -0
- package/dist/rules/no-dupe-class-members.js +39 -0
- package/dist/rules/no-duplicate-enum-values.d.ts +4 -0
- package/dist/rules/no-duplicate-enum-values.js +83 -0
- package/dist/rules/no-duplicate-type-constituents.d.ts +11 -0
- package/dist/rules/no-duplicate-type-constituents.js +219 -0
- package/dist/rules/no-dynamic-delete.d.ts +4 -0
- package/dist/rules/no-dynamic-delete.js +42 -0
- package/dist/rules/no-empty-function.d.ts +16 -0
- package/dist/rules/no-empty-function.js +134 -0
- package/dist/rules/no-empty-interface.d.ts +11 -0
- package/dist/rules/no-empty-interface.js +102 -0
- package/dist/rules/no-empty-object-type.d.ts +15 -0
- package/dist/rules/no-empty-object-type.js +143 -0
- package/dist/rules/no-explicit-any.d.ts +12 -0
- package/dist/rules/no-explicit-any.js +197 -0
- package/dist/rules/no-extra-non-null-assertion.d.ts +4 -0
- package/dist/rules/no-extra-non-null-assertion.js +35 -0
- package/dist/rules/no-extraneous-class.d.ts +13 -0
- package/dist/rules/no-extraneous-class.js +120 -0
- package/dist/rules/no-floating-promises.d.ts +16 -0
- package/dist/rules/no-floating-promises.js +365 -0
- package/dist/rules/no-for-in-array.d.ts +4 -0
- package/dist/rules/no-for-in-array.js +86 -0
- package/dist/rules/no-implied-eval.d.ts +4 -0
- package/dist/rules/no-implied-eval.js +152 -0
- package/dist/rules/no-import-type-side-effects.d.ts +7 -0
- package/dist/rules/no-import-type-side-effects.js +53 -0
- package/dist/rules/no-inferrable-types.d.ts +11 -0
- package/dist/rules/no-inferrable-types.js +182 -0
- package/dist/rules/no-invalid-this.d.ts +15 -0
- package/dist/rules/no-invalid-this.js +75 -0
- package/dist/rules/no-invalid-void-type.d.ts +9 -0
- package/dist/rules/no-invalid-void-type.js +210 -0
- package/dist/rules/no-loop-func.d.ts +13 -0
- package/dist/rules/no-loop-func.js +187 -0
- package/dist/rules/no-loss-of-precision.d.ts +9 -0
- package/dist/rules/no-loss-of-precision.js +35 -0
- package/dist/rules/no-magic-numbers.d.ts +29 -0
- package/dist/rules/no-magic-numbers.js +248 -0
- package/dist/rules/no-meaningless-void-operator.d.ts +10 -0
- package/dist/rules/no-meaningless-void-operator.js +102 -0
- package/dist/rules/no-misused-new.d.ts +4 -0
- package/dist/rules/no-misused-new.js +81 -0
- package/dist/rules/no-misused-promises.d.ts +21 -0
- package/dist/rules/no-misused-promises.js +765 -0
- package/dist/rules/no-misused-spread.d.ts +12 -0
- package/dist/rules/no-misused-spread.js +260 -0
- package/dist/rules/no-mixed-enums.d.ts +4 -0
- package/dist/rules/no-mixed-enums.js +200 -0
- package/dist/rules/no-namespace.d.ts +11 -0
- package/dist/rules/no-namespace.js +60 -0
- package/dist/rules/no-non-null-asserted-nullish-coalescing.d.ts +5 -0
- package/dist/rules/no-non-null-asserted-nullish-coalescing.js +73 -0
- package/dist/rules/no-non-null-asserted-optional-chain.d.ts +5 -0
- package/dist/rules/no-non-null-asserted-optional-chain.js +65 -0
- package/dist/rules/no-non-null-assertion.d.ts +6 -0
- package/dist/rules/no-non-null-assertion.js +93 -0
- package/dist/rules/no-redeclare.d.ts +12 -0
- package/dist/rules/no-redeclare.js +199 -0
- package/dist/rules/no-redundant-type-constituents.d.ts +4 -0
- package/dist/rules/no-redundant-type-constituents.js +431 -0
- package/dist/rules/no-require-imports.d.ts +11 -0
- package/dist/rules/no-require-imports.js +115 -0
- package/dist/rules/no-restricted-imports.d.ts +9 -0
- package/dist/rules/no-restricted-imports.js +243 -0
- package/dist/rules/no-restricted-types.d.ts +16 -0
- package/dist/rules/no-restricted-types.js +165 -0
- package/dist/rules/no-shadow.d.ts +16 -0
- package/dist/rules/no-shadow.js +521 -0
- package/dist/rules/no-this-alias.d.ts +11 -0
- package/dist/rules/no-this-alias.js +66 -0
- package/dist/rules/no-type-alias.d.ts +18 -0
- package/dist/rules/no-type-alias.js +268 -0
- package/dist/rules/no-unnecessary-boolean-literal-compare.d.ts +12 -0
- package/dist/rules/no-unnecessary-boolean-literal-compare.js +263 -0
- package/dist/rules/no-unnecessary-condition.d.ts +14 -0
- package/dist/rules/no-unnecessary-condition.js +675 -0
- package/dist/rules/no-unnecessary-parameter-property-assignment.d.ts +4 -0
- package/dist/rules/no-unnecessary-parameter-property-assignment.js +148 -0
- package/dist/rules/no-unnecessary-qualifier.d.ts +4 -0
- package/dist/rules/no-unnecessary-qualifier.js +156 -0
- package/dist/rules/no-unnecessary-template-expression.d.ts +6 -0
- package/dist/rules/no-unnecessary-template-expression.js +361 -0
- package/dist/rules/no-unnecessary-type-arguments.d.ts +5 -0
- package/dist/rules/no-unnecessary-type-arguments.js +197 -0
- package/dist/rules/no-unnecessary-type-assertion.d.ts +11 -0
- package/dist/rules/no-unnecessary-type-assertion.js +353 -0
- package/dist/rules/no-unnecessary-type-constraint.d.ts +5 -0
- package/dist/rules/no-unnecessary-type-constraint.js +119 -0
- package/dist/rules/no-unnecessary-type-conversion.d.ts +5 -0
- package/dist/rules/no-unnecessary-type-conversion.js +356 -0
- package/dist/rules/no-unnecessary-type-parameters.d.ts +5 -0
- package/dist/rules/no-unnecessary-type-parameters.js +422 -0
- package/dist/rules/no-unsafe-argument.d.ts +5 -0
- package/dist/rules/no-unsafe-argument.js +272 -0
- package/dist/rules/no-unsafe-assignment.d.ts +4 -0
- package/dist/rules/no-unsafe-assignment.js +322 -0
- package/dist/rules/no-unsafe-call.d.ts +5 -0
- package/dist/rules/no-unsafe-call.js +136 -0
- package/dist/rules/no-unsafe-declaration-merging.d.ts +4 -0
- package/dist/rules/no-unsafe-declaration-merging.js +54 -0
- package/dist/rules/no-unsafe-enum-comparison.d.ts +5 -0
- package/dist/rules/no-unsafe-enum-comparison.js +192 -0
- package/dist/rules/no-unsafe-function-type.d.ts +4 -0
- package/dist/rules/no-unsafe-function-type.js +45 -0
- package/dist/rules/no-unsafe-member-access.d.ts +10 -0
- package/dist/rules/no-unsafe-member-access.js +183 -0
- package/dist/rules/no-unsafe-return.d.ts +4 -0
- package/dist/rules/no-unsafe-return.js +183 -0
- package/dist/rules/no-unsafe-type-assertion.d.ts +4 -0
- package/dist/rules/no-unsafe-type-assertion.js +158 -0
- package/dist/rules/no-unsafe-unary-minus.d.ts +6 -0
- package/dist/rules/no-unsafe-unary-minus.js +78 -0
- package/dist/rules/no-unused-expressions.d.ts +19 -0
- package/dist/rules/no-unused-expressions.js +64 -0
- package/dist/rules/no-unused-private-class-members.d.ts +6 -0
- package/dist/rules/no-unused-private-class-members.js +44 -0
- package/dist/rules/no-unused-vars.d.ts +24 -0
- package/dist/rules/no-unused-vars.js +1033 -0
- package/dist/rules/no-use-before-define.d.ts +16 -0
- package/dist/rules/no-use-before-define.js +303 -0
- package/dist/rules/no-useless-constructor.d.ts +11 -0
- package/dist/rules/no-useless-constructor.js +57 -0
- package/dist/rules/no-useless-default-assignment.d.ts +11 -0
- package/dist/rules/no-useless-default-assignment.js +318 -0
- package/dist/rules/no-useless-empty-export.d.ts +4 -0
- package/dist/rules/no-useless-empty-export.js +70 -0
- package/dist/rules/no-var-requires.d.ts +10 -0
- package/dist/rules/no-var-requires.js +83 -0
- package/dist/rules/no-wrapper-object-types.d.ts +5 -0
- package/dist/rules/no-wrapper-object-types.js +60 -0
- package/dist/rules/non-nullable-type-assertion-style.d.ts +4 -0
- package/dist/rules/non-nullable-type-assertion-style.js +132 -0
- package/dist/rules/only-throw-error.d.ts +14 -0
- package/dist/rules/only-throw-error.js +158 -0
- package/dist/rules/parameter-properties.d.ts +13 -0
- package/dist/rules/parameter-properties.js +164 -0
- package/dist/rules/prefer-as-const.d.ts +5 -0
- package/dist/rules/prefer-as-const.js +72 -0
- package/dist/rules/prefer-destructuring.d.ts +19 -0
- package/dist/rules/prefer-destructuring.js +216 -0
- package/dist/rules/prefer-enum-initializers.d.ts +6 -0
- package/dist/rules/prefer-enum-initializers.js +62 -0
- package/dist/rules/prefer-find.d.ts +5 -0
- package/dist/rules/prefer-find.js +247 -0
- package/dist/rules/prefer-for-of.d.ts +5 -0
- package/dist/rules/prefer-for-of.js +115 -0
- package/dist/rules/prefer-function-type.d.ts +9 -0
- package/dist/rules/prefer-function-type.js +186 -0
- package/dist/rules/prefer-includes.d.ts +5 -0
- package/dist/rules/prefer-includes.js +242 -0
- package/dist/rules/prefer-literal-enum-member.d.ts +6 -0
- package/dist/rules/prefer-literal-enum-member.js +116 -0
- package/dist/rules/prefer-namespace-keyword.d.ts +4 -0
- package/dist/rules/prefer-namespace-keyword.js +42 -0
- package/dist/rules/prefer-nullish-coalescing.d.ts +22 -0
- package/dist/rules/prefer-nullish-coalescing.js +647 -0
- package/dist/rules/prefer-optional-chain-utils/PreferOptionalChainOptions.d.ts +11 -0
- package/dist/rules/prefer-optional-chain-utils/PreferOptionalChainOptions.js +2 -0
- package/dist/rules/prefer-optional-chain-utils/analyzeChain.d.ts +7 -0
- package/dist/rules/prefer-optional-chain-utils/analyzeChain.js +569 -0
- package/dist/rules/prefer-optional-chain-utils/checkNullishAndReport.d.ts +6 -0
- package/dist/rules/prefer-optional-chain-utils/checkNullishAndReport.js +45 -0
- package/dist/rules/prefer-optional-chain-utils/compareNodes.d.ts +15 -0
- package/dist/rules/prefer-optional-chain-utils/compareNodes.js +326 -0
- package/dist/rules/prefer-optional-chain-utils/gatherLogicalOperands.d.ts +61 -0
- package/dist/rules/prefer-optional-chain-utils/gatherLogicalOperands.js +411 -0
- package/dist/rules/prefer-optional-chain.d.ts +5 -0
- package/dist/rules/prefer-optional-chain.js +150 -0
- package/dist/rules/prefer-promise-reject-errors.d.ts +14 -0
- package/dist/rules/prefer-promise-reject-errors.js +124 -0
- package/dist/rules/prefer-readonly-parameter-types.d.ts +14 -0
- package/dist/rules/prefer-readonly-parameter-types.js +89 -0
- package/dist/rules/prefer-readonly.d.ts +10 -0
- package/dist/rules/prefer-readonly.js +439 -0
- package/dist/rules/prefer-reduce-type-parameter.d.ts +4 -0
- package/dist/rules/prefer-reduce-type-parameter.js +114 -0
- package/dist/rules/prefer-regexp-exec.d.ts +4 -0
- package/dist/rules/prefer-regexp-exec.js +178 -0
- package/dist/rules/prefer-return-this-type.d.ts +4 -0
- package/dist/rules/prefer-return-this-type.js +154 -0
- package/dist/rules/prefer-string-starts-ends-with.d.ts +12 -0
- package/dist/rules/prefer-string-starts-ends-with.js +512 -0
- package/dist/rules/prefer-ts-expect-error.d.ts +5 -0
- package/dist/rules/prefer-ts-expect-error.js +71 -0
- package/dist/rules/promise-function-async.d.ts +15 -0
- package/dist/rules/promise-function-async.js +204 -0
- package/dist/rules/related-getter-setter-pairs.d.ts +4 -0
- package/dist/rules/related-getter-setter-pairs.js +71 -0
- package/dist/rules/require-array-sort-compare.d.ts +10 -0
- package/dist/rules/require-array-sort-compare.js +63 -0
- package/dist/rules/require-await.d.ts +4 -0
- package/dist/rules/require-await.js +263 -0
- package/dist/rules/restrict-plus-operands.d.ts +15 -0
- package/dist/rules/restrict-plus-operands.js +231 -0
- package/dist/rules/restrict-template-expressions.d.ts +19 -0
- package/dist/rules/restrict-template-expressions.js +119 -0
- package/dist/rules/return-await.d.ts +5 -0
- package/dist/rules/return-await.js +363 -0
- package/dist/rules/sort-type-constituents.d.ts +14 -0
- package/dist/rules/sort-type-constituents.js +272 -0
- package/dist/rules/strict-boolean-expressions.d.ts +19 -0
- package/dist/rules/strict-boolean-expressions.js +882 -0
- package/dist/rules/strict-void-return.d.ts +10 -0
- package/dist/rules/strict-void-return.js +374 -0
- package/dist/rules/switch-exhaustiveness-check.d.ts +33 -0
- package/dist/rules/switch-exhaustiveness-check.js +291 -0
- package/dist/rules/triple-slash-reference.d.ts +12 -0
- package/dist/rules/triple-slash-reference.js +110 -0
- package/dist/rules/typedef.d.ts +16 -0
- package/dist/rules/typedef.js +239 -0
- package/dist/rules/unbound-method.d.ts +9 -0
- package/dist/rules/unbound-method.js +334 -0
- package/dist/rules/unified-signatures.d.ts +11 -0
- package/dist/rules/unified-signatures.js +465 -0
- package/dist/rules/use-unknown-in-catch-callback-variable.d.ts +6 -0
- package/dist/rules/use-unknown-in-catch-callback-variable.js +261 -0
- package/dist/util/assertionFunctionUtils.d.ts +16 -0
- package/dist/util/assertionFunctionUtils.js +116 -0
- package/dist/util/astUtils.d.ts +17 -0
- package/dist/util/astUtils.js +143 -0
- package/dist/util/baseTypeUtils.d.ts +13 -0
- package/dist/util/baseTypeUtils.js +75 -0
- package/dist/util/class-scope-analyzer/classScopeAnalyzer.d.ts +52 -0
- package/dist/util/class-scope-analyzer/classScopeAnalyzer.js +566 -0
- package/dist/util/class-scope-analyzer/extractComputedName.d.ts +17 -0
- package/dist/util/class-scope-analyzer/extractComputedName.js +70 -0
- package/dist/util/class-scope-analyzer/types.d.ts +12 -0
- package/dist/util/class-scope-analyzer/types.js +10 -0
- package/dist/util/collectUnusedVariables.d.ts +15 -0
- package/dist/util/collectUnusedVariables.js +598 -0
- package/dist/util/createRule.d.ts +5 -0
- package/dist/util/createRule.js +5 -0
- package/dist/util/escapeRegExp.d.ts +1 -0
- package/dist/util/escapeRegExp.js +14 -0
- package/dist/util/explicitReturnTypeUtils.d.ts +47 -0
- package/dist/util/explicitReturnTypeUtils.js +238 -0
- package/dist/util/getBaseTypesOfClassMember.d.ts +11 -0
- package/dist/util/getBaseTypesOfClassMember.js +31 -0
- package/dist/util/getConstraintInfo.d.ts +35 -0
- package/dist/util/getConstraintInfo.js +70 -0
- package/dist/util/getESLintCoreRule.d.ts +27 -0
- package/dist/util/getESLintCoreRule.js +16 -0
- package/dist/util/getFixOrSuggest.d.ts +9 -0
- package/dist/util/getFixOrSuggest.js +13 -0
- package/dist/util/getForStatementHeadLoc.d.ts +17 -0
- package/dist/util/getForStatementHeadLoc.js +26 -0
- package/dist/util/getFunctionHeadLoc.d.ts +101 -0
- package/dist/util/getFunctionHeadLoc.js +161 -0
- package/dist/util/getMemberHeadLoc.d.ts +36 -0
- package/dist/util/getMemberHeadLoc.js +79 -0
- package/dist/util/getOperatorPrecedence.d.ts +39 -0
- package/dist/util/getOperatorPrecedence.js +421 -0
- package/dist/util/getParentFunctionNode.d.ts +2 -0
- package/dist/util/getParentFunctionNode.js +18 -0
- package/dist/util/getStaticStringValue.d.ts +11 -0
- package/dist/util/getStaticStringValue.js +44 -0
- package/dist/util/getStringLength.d.ts +1 -0
- package/dist/util/getStringLength.js +14 -0
- package/dist/util/getTextWithParentheses.d.ts +3 -0
- package/dist/util/getTextWithParentheses.js +16 -0
- package/dist/util/getThisExpression.d.ts +2 -0
- package/dist/util/getThisExpression.js +24 -0
- package/dist/util/getValueOfLiteralType.d.ts +2 -0
- package/dist/util/getValueOfLiteralType.js +16 -0
- package/dist/util/getWrappedCode.d.ts +2 -0
- package/dist/util/getWrappedCode.js +6 -0
- package/dist/util/getWrappingFixer.d.ts +42 -0
- package/dist/util/getWrappingFixer.js +184 -0
- package/dist/util/hasOverloadSignatures.d.ts +6 -0
- package/dist/util/hasOverloadSignatures.js +47 -0
- package/dist/util/index.d.ts +40 -0
- package/dist/util/index.js +53 -0
- package/dist/util/isArrayMethodCallWithPredicate.d.ts +3 -0
- package/dist/util/isArrayMethodCallWithPredicate.js +64 -0
- package/dist/util/isAssignee.d.ts +2 -0
- package/dist/util/isAssignee.js +50 -0
- package/dist/util/isHigherPrecedenceThanAwait.d.ts +2 -0
- package/dist/util/isHigherPrecedenceThanAwait.js +46 -0
- package/dist/util/isNodeEqual.d.ts +2 -0
- package/dist/util/isNodeEqual.js +25 -0
- package/dist/util/isNullLiteral.d.ts +2 -0
- package/dist/util/isNullLiteral.js +7 -0
- package/dist/util/isPromiseAggregatorMethod.d.ts +3 -0
- package/dist/util/isPromiseAggregatorMethod.js +22 -0
- package/dist/util/isStartOfExpressionStatement.d.ts +7 -0
- package/dist/util/isStartOfExpressionStatement.js +22 -0
- package/dist/util/isTypeImport.d.ts +12 -0
- package/dist/util/isTypeImport.js +21 -0
- package/dist/util/isUndefinedIdentifier.d.ts +2 -0
- package/dist/util/isUndefinedIdentifier.js +7 -0
- package/dist/util/misc.d.ts +115 -0
- package/dist/util/misc.js +270 -0
- package/dist/util/needsPrecedingSemiColon.d.ts +11 -0
- package/dist/util/needsPrecedingSemiColon.js +97 -0
- package/dist/util/needsToBeAwaited.d.ts +7 -0
- package/dist/util/needsToBeAwaited.js +63 -0
- package/dist/util/objectIterators.d.ts +3 -0
- package/dist/util/objectIterators.js +25 -0
- package/dist/util/promiseUtils.d.ts +27 -0
- package/dist/util/promiseUtils.js +98 -0
- package/dist/util/rangeToLoc.d.ts +2 -0
- package/dist/util/rangeToLoc.js +9 -0
- package/dist/util/referenceContainsTypeQuery.d.ts +5 -0
- package/dist/util/referenceContainsTypeQuery.js +19 -0
- package/dist/util/scopeUtils.d.ts +3 -0
- package/dist/util/scopeUtils.js +10 -0
- package/dist/util/skipChainExpression.d.ts +2 -0
- package/dist/util/skipChainExpression.js +7 -0
- package/dist/util/truthinessUtils.d.ts +3 -0
- package/dist/util/truthinessUtils.js +60 -0
- package/dist/util/types.d.ts +2 -0
- package/dist/util/types.js +2 -0
- package/dist/util/walkStatements.d.ts +7 -0
- package/dist/util/walkStatements.js +56 -0
- package/index.d.ts +13 -0
- package/package.json +137 -0
- package/raw-plugin.d.ts +25 -0
- package/rules.d.ts +87 -0
|
@@ -0,0 +1,675 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
const utils_1 = require("@typescript-eslint/utils");
|
|
37
|
+
const tsutils = __importStar(require("ts-api-utils"));
|
|
38
|
+
const ts = __importStar(require("typescript"));
|
|
39
|
+
const util_1 = require("../util");
|
|
40
|
+
const assertionFunctionUtils_1 = require("../util/assertionFunctionUtils");
|
|
41
|
+
// #region
|
|
42
|
+
const nullishFlag = ts.TypeFlags.Undefined | ts.TypeFlags.Null;
|
|
43
|
+
function isNullishType(type) {
|
|
44
|
+
return tsutils.isTypeFlagSet(type, nullishFlag);
|
|
45
|
+
}
|
|
46
|
+
function isAlwaysNullish(type) {
|
|
47
|
+
return tsutils.unionConstituents(type).every(isNullishType);
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Note that this differs from {@link isNullableType} in that it doesn't consider
|
|
51
|
+
* `any` or `unknown` to be nullable.
|
|
52
|
+
*/
|
|
53
|
+
function isPossiblyNullish(type) {
|
|
54
|
+
return tsutils.unionConstituents(type).some(isNullishType);
|
|
55
|
+
}
|
|
56
|
+
function toStaticValue(type) {
|
|
57
|
+
// type.isLiteral() only covers numbers/bigints and strings, hence the rest of the branches.
|
|
58
|
+
if (tsutils.isBooleanLiteralType(type)) {
|
|
59
|
+
return { value: tsutils.isTrueLiteralType(type) };
|
|
60
|
+
}
|
|
61
|
+
if (type.flags === ts.TypeFlags.Undefined) {
|
|
62
|
+
return { value: undefined };
|
|
63
|
+
}
|
|
64
|
+
if (type.flags === ts.TypeFlags.Null) {
|
|
65
|
+
return { value: null };
|
|
66
|
+
}
|
|
67
|
+
if (type.isLiteral()) {
|
|
68
|
+
return { value: (0, util_1.getValueOfLiteralType)(type) };
|
|
69
|
+
}
|
|
70
|
+
return undefined;
|
|
71
|
+
}
|
|
72
|
+
const BOOL_OPERATORS = new Set([
|
|
73
|
+
'<',
|
|
74
|
+
'>',
|
|
75
|
+
'<=',
|
|
76
|
+
'>=',
|
|
77
|
+
'==',
|
|
78
|
+
'===',
|
|
79
|
+
'!=',
|
|
80
|
+
'!==',
|
|
81
|
+
]);
|
|
82
|
+
function isBoolOperator(operator) {
|
|
83
|
+
return BOOL_OPERATORS.has(operator);
|
|
84
|
+
}
|
|
85
|
+
function booleanComparison(left, operator, right) {
|
|
86
|
+
switch (operator) {
|
|
87
|
+
case '!=':
|
|
88
|
+
// eslint-disable-next-line eqeqeq -- intentionally comparing with loose equality
|
|
89
|
+
return left != right;
|
|
90
|
+
case '!==':
|
|
91
|
+
return left !== right;
|
|
92
|
+
case '<':
|
|
93
|
+
// @ts-expect-error: we don't care if the comparison seems unintentional.
|
|
94
|
+
return left < right;
|
|
95
|
+
case '<=':
|
|
96
|
+
// @ts-expect-error: we don't care if the comparison seems unintentional.
|
|
97
|
+
return left <= right;
|
|
98
|
+
case '==':
|
|
99
|
+
// eslint-disable-next-line eqeqeq -- intentionally comparing with loose equality
|
|
100
|
+
return left == right;
|
|
101
|
+
case '===':
|
|
102
|
+
return left === right;
|
|
103
|
+
case '>':
|
|
104
|
+
// @ts-expect-error: we don't care if the comparison seems unintentional.
|
|
105
|
+
return left > right;
|
|
106
|
+
case '>=':
|
|
107
|
+
// @ts-expect-error: we don't care if the comparison seems unintentional.
|
|
108
|
+
return left >= right;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
const constantLoopConditionsAllowedLiterals = new Set([
|
|
112
|
+
true,
|
|
113
|
+
false,
|
|
114
|
+
1,
|
|
115
|
+
0,
|
|
116
|
+
]);
|
|
117
|
+
exports.default = (0, util_1.createRule)({
|
|
118
|
+
name: 'no-unnecessary-condition',
|
|
119
|
+
meta: {
|
|
120
|
+
type: 'suggestion',
|
|
121
|
+
docs: {
|
|
122
|
+
description: 'Disallow conditionals where the type is always truthy or always falsy',
|
|
123
|
+
recommended: 'strict',
|
|
124
|
+
requiresTypeChecking: true,
|
|
125
|
+
},
|
|
126
|
+
hasSuggestions: true,
|
|
127
|
+
messages: {
|
|
128
|
+
alwaysFalsy: 'Unnecessary conditional, value is always falsy.',
|
|
129
|
+
alwaysFalsyFunc: 'This callback should return a conditional, but return is always falsy.',
|
|
130
|
+
alwaysNullish: 'Unnecessary conditional, left-hand side of `??` operator is always `null` or `undefined`.',
|
|
131
|
+
alwaysTruthy: 'Unnecessary conditional, value is always truthy.',
|
|
132
|
+
alwaysTruthyFunc: 'This callback should return a conditional, but return is always truthy.',
|
|
133
|
+
comparisonBetweenLiteralTypes: 'Unnecessary conditional, comparison is always {{trueOrFalse}}, since `{{left}} {{operator}} {{right}}` is {{trueOrFalse}}.',
|
|
134
|
+
never: 'Unnecessary conditional, value is `never`.',
|
|
135
|
+
neverNullish: 'Unnecessary conditional, expected left-hand side of `??` operator to be possibly null or undefined.',
|
|
136
|
+
neverOptionalChain: 'Unnecessary optional chain on a non-nullish value.',
|
|
137
|
+
noOverlapBooleanExpression: 'Unnecessary conditional, the types have no overlap.',
|
|
138
|
+
noStrictNullCheck: 'This rule requires the `strictNullChecks` compiler option to be turned on to function correctly.',
|
|
139
|
+
suggestRemoveOptionalChain: 'Remove unnecessary optional chain',
|
|
140
|
+
typeGuardAlreadyIsType: 'Unnecessary conditional, expression already has the type being checked by the {{typeGuardOrAssertionFunction}}.',
|
|
141
|
+
},
|
|
142
|
+
schema: [
|
|
143
|
+
{
|
|
144
|
+
type: 'object',
|
|
145
|
+
additionalProperties: false,
|
|
146
|
+
properties: {
|
|
147
|
+
allowConstantLoopConditions: {
|
|
148
|
+
description: 'Whether to ignore constant loop conditions, such as `while (true)`.',
|
|
149
|
+
oneOf: [
|
|
150
|
+
{
|
|
151
|
+
type: 'boolean',
|
|
152
|
+
description: 'Always ignore or not ignore the loop conditions',
|
|
153
|
+
},
|
|
154
|
+
{
|
|
155
|
+
type: 'string',
|
|
156
|
+
description: 'Which situations to ignore constant conditions in.',
|
|
157
|
+
enum: ['always', 'never', 'only-allowed-literals'],
|
|
158
|
+
},
|
|
159
|
+
],
|
|
160
|
+
},
|
|
161
|
+
allowRuleToRunWithoutStrictNullChecksIKnowWhatIAmDoing: {
|
|
162
|
+
type: 'boolean',
|
|
163
|
+
description: 'Whether to not error when running with a tsconfig that has strictNullChecks turned.',
|
|
164
|
+
},
|
|
165
|
+
checkTypePredicates: {
|
|
166
|
+
type: 'boolean',
|
|
167
|
+
description: 'Whether to check the asserted argument of a type predicate function for unnecessary conditions',
|
|
168
|
+
},
|
|
169
|
+
},
|
|
170
|
+
},
|
|
171
|
+
],
|
|
172
|
+
},
|
|
173
|
+
defaultOptions: [
|
|
174
|
+
{
|
|
175
|
+
allowConstantLoopConditions: 'never',
|
|
176
|
+
allowRuleToRunWithoutStrictNullChecksIKnowWhatIAmDoing: false,
|
|
177
|
+
checkTypePredicates: false,
|
|
178
|
+
},
|
|
179
|
+
],
|
|
180
|
+
create(context, [{ allowConstantLoopConditions, allowRuleToRunWithoutStrictNullChecksIKnowWhatIAmDoing, checkTypePredicates, },]) {
|
|
181
|
+
const services = (0, util_1.getParserServices)(context);
|
|
182
|
+
const checker = services.program.getTypeChecker();
|
|
183
|
+
const compilerOptions = services.program.getCompilerOptions();
|
|
184
|
+
const isStrictNullChecks = tsutils.isStrictCompilerOptionEnabled(compilerOptions, 'strictNullChecks');
|
|
185
|
+
const isNoUncheckedIndexedAccess = tsutils.isCompilerOptionEnabled(compilerOptions, 'noUncheckedIndexedAccess');
|
|
186
|
+
const allowConstantLoopConditionsOption = normalizeAllowConstantLoopConditions(
|
|
187
|
+
// https://github.com/typescript-eslint/typescript-eslint/issues/5439
|
|
188
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
189
|
+
allowConstantLoopConditions);
|
|
190
|
+
if (!isStrictNullChecks &&
|
|
191
|
+
allowRuleToRunWithoutStrictNullChecksIKnowWhatIAmDoing !== true) {
|
|
192
|
+
context.report({
|
|
193
|
+
loc: {
|
|
194
|
+
start: { column: 0, line: 0 },
|
|
195
|
+
end: { column: 0, line: 0 },
|
|
196
|
+
},
|
|
197
|
+
messageId: 'noStrictNullCheck',
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
function nodeIsArrayType(node) {
|
|
201
|
+
const nodeType = (0, util_1.getConstrainedTypeAtLocation)(services, node);
|
|
202
|
+
return tsutils
|
|
203
|
+
.unionConstituents(nodeType)
|
|
204
|
+
.some(part => checker.isArrayType(part));
|
|
205
|
+
}
|
|
206
|
+
function nodeIsTupleType(node) {
|
|
207
|
+
const nodeType = (0, util_1.getConstrainedTypeAtLocation)(services, node);
|
|
208
|
+
return tsutils
|
|
209
|
+
.unionConstituents(nodeType)
|
|
210
|
+
.some(part => checker.isTupleType(part));
|
|
211
|
+
}
|
|
212
|
+
function isArrayIndexExpression(node) {
|
|
213
|
+
return (
|
|
214
|
+
// Is an index signature
|
|
215
|
+
node.type === utils_1.AST_NODE_TYPES.MemberExpression &&
|
|
216
|
+
node.computed &&
|
|
217
|
+
// ...into an array type
|
|
218
|
+
(nodeIsArrayType(node.object) ||
|
|
219
|
+
// ... or a tuple type
|
|
220
|
+
(nodeIsTupleType(node.object) &&
|
|
221
|
+
// Exception: literal index into a tuple - will have a sound type
|
|
222
|
+
node.property.type !== utils_1.AST_NODE_TYPES.Literal)));
|
|
223
|
+
}
|
|
224
|
+
// Conditional is always necessary if it involves:
|
|
225
|
+
// `any` or `unknown` or a naked type variable
|
|
226
|
+
function isConditionalAlwaysNecessary(type) {
|
|
227
|
+
return tsutils
|
|
228
|
+
.unionConstituents(type)
|
|
229
|
+
.some(part => (0, util_1.isTypeAnyType)(part) ||
|
|
230
|
+
(0, util_1.isTypeUnknownType)(part) ||
|
|
231
|
+
(0, util_1.isTypeFlagSet)(part, ts.TypeFlags.TypeVariable));
|
|
232
|
+
}
|
|
233
|
+
function isNullableMemberExpression(node) {
|
|
234
|
+
const objectType = services.getTypeAtLocation(node.object);
|
|
235
|
+
if (node.computed) {
|
|
236
|
+
const propertyType = services.getTypeAtLocation(node.property);
|
|
237
|
+
return isNullablePropertyType(objectType, propertyType);
|
|
238
|
+
}
|
|
239
|
+
const property = node.property;
|
|
240
|
+
// Get the actual property name, to account for private properties (this.#prop).
|
|
241
|
+
const propertyName = context.sourceCode.getText(property);
|
|
242
|
+
const propertyType = objectType
|
|
243
|
+
.getProperties()
|
|
244
|
+
.find(prop => prop.name === propertyName);
|
|
245
|
+
if (propertyType &&
|
|
246
|
+
tsutils.isSymbolFlagSet(propertyType, ts.SymbolFlags.Optional)) {
|
|
247
|
+
return true;
|
|
248
|
+
}
|
|
249
|
+
return false;
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* Checks if a conditional node is necessary:
|
|
253
|
+
* if the type of the node is always true or always false, it's not necessary.
|
|
254
|
+
*/
|
|
255
|
+
function checkNode(expression, isUnaryNotArgument = false, node = expression) {
|
|
256
|
+
// Check if the node is Unary Negation expression and handle it
|
|
257
|
+
if (expression.type === utils_1.AST_NODE_TYPES.UnaryExpression &&
|
|
258
|
+
expression.operator === '!') {
|
|
259
|
+
return checkNode(expression.argument, !isUnaryNotArgument, node);
|
|
260
|
+
}
|
|
261
|
+
// Since typescript array index signature types don't represent the
|
|
262
|
+
// possibility of out-of-bounds access, if we're indexing into an array
|
|
263
|
+
// just skip the check, to avoid false positives
|
|
264
|
+
if (!isNoUncheckedIndexedAccess && isArrayIndexExpression(expression)) {
|
|
265
|
+
return;
|
|
266
|
+
}
|
|
267
|
+
// When checking logical expressions, only check the right side
|
|
268
|
+
// as the left side has been checked by checkLogicalExpressionForUnnecessaryConditionals
|
|
269
|
+
//
|
|
270
|
+
// Unless the node is nullish coalescing, as it's common to use patterns like `nullBool ?? true` to to strict
|
|
271
|
+
// boolean checks if we inspect the right here, it'll usually be a constant condition on purpose.
|
|
272
|
+
// In this case it's better to inspect the type of the expression as a whole.
|
|
273
|
+
if (expression.type === utils_1.AST_NODE_TYPES.LogicalExpression &&
|
|
274
|
+
expression.operator !== '??') {
|
|
275
|
+
return checkNode(expression.right);
|
|
276
|
+
}
|
|
277
|
+
const type = (0, util_1.getConstrainedTypeAtLocation)(services, expression);
|
|
278
|
+
if (isConditionalAlwaysNecessary(type)) {
|
|
279
|
+
return;
|
|
280
|
+
}
|
|
281
|
+
let messageId = null;
|
|
282
|
+
if ((0, util_1.isTypeFlagSet)(type, ts.TypeFlags.Never)) {
|
|
283
|
+
messageId = 'never';
|
|
284
|
+
}
|
|
285
|
+
else if (!(0, util_1.isPossiblyTruthy)(type)) {
|
|
286
|
+
messageId = !isUnaryNotArgument ? 'alwaysFalsy' : 'alwaysTruthy';
|
|
287
|
+
}
|
|
288
|
+
else if (!(0, util_1.isPossiblyFalsy)(type)) {
|
|
289
|
+
messageId = !isUnaryNotArgument ? 'alwaysTruthy' : 'alwaysFalsy';
|
|
290
|
+
}
|
|
291
|
+
if (messageId) {
|
|
292
|
+
context.report({ node, messageId });
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
function checkNodeForNullish(node) {
|
|
296
|
+
const type = (0, util_1.getConstrainedTypeAtLocation)(services, node);
|
|
297
|
+
// Conditional is always necessary if it involves `any`, `unknown` or a naked type parameter
|
|
298
|
+
if ((0, util_1.isTypeFlagSet)(type, ts.TypeFlags.Any |
|
|
299
|
+
ts.TypeFlags.Unknown |
|
|
300
|
+
ts.TypeFlags.TypeParameter |
|
|
301
|
+
ts.TypeFlags.TypeVariable)) {
|
|
302
|
+
return;
|
|
303
|
+
}
|
|
304
|
+
let messageId = null;
|
|
305
|
+
if ((0, util_1.isTypeFlagSet)(type, ts.TypeFlags.Never)) {
|
|
306
|
+
messageId = 'never';
|
|
307
|
+
}
|
|
308
|
+
else if (!isPossiblyNullish(type) &&
|
|
309
|
+
!(node.type === utils_1.AST_NODE_TYPES.MemberExpression &&
|
|
310
|
+
isNullableMemberExpression(node))) {
|
|
311
|
+
// Since typescript array index signature types don't represent the
|
|
312
|
+
// possibility of out-of-bounds access, if we're indexing into an array
|
|
313
|
+
// just skip the check, to avoid false positives
|
|
314
|
+
if (isNoUncheckedIndexedAccess ||
|
|
315
|
+
(!isArrayIndexExpression(node) &&
|
|
316
|
+
!(node.type === utils_1.AST_NODE_TYPES.ChainExpression &&
|
|
317
|
+
node.expression.type !== utils_1.AST_NODE_TYPES.TSNonNullExpression &&
|
|
318
|
+
optionChainContainsOptionArrayIndex(node.expression)))) {
|
|
319
|
+
messageId = 'neverNullish';
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
else if (isAlwaysNullish(type)) {
|
|
323
|
+
messageId = 'alwaysNullish';
|
|
324
|
+
}
|
|
325
|
+
if (messageId) {
|
|
326
|
+
context.report({ node, messageId });
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
/**
|
|
330
|
+
* Checks that a binary expression is necessarily conditional, reports otherwise.
|
|
331
|
+
* If both sides of the binary expression are literal values, it's not a necessary condition.
|
|
332
|
+
*
|
|
333
|
+
* NOTE: It's also unnecessary if the types that don't overlap at all
|
|
334
|
+
* but that case is handled by the Typescript compiler itself.
|
|
335
|
+
* Known exceptions:
|
|
336
|
+
* - https://github.com/microsoft/TypeScript/issues/32627
|
|
337
|
+
* - https://github.com/microsoft/TypeScript/issues/37160 (handled)
|
|
338
|
+
*/
|
|
339
|
+
function checkIfBoolExpressionIsNecessaryConditional(node, left, right, operator) {
|
|
340
|
+
const leftType = (0, util_1.getConstrainedTypeAtLocation)(services, left);
|
|
341
|
+
const rightType = (0, util_1.getConstrainedTypeAtLocation)(services, right);
|
|
342
|
+
const leftStaticValue = toStaticValue(leftType);
|
|
343
|
+
const rightStaticValue = toStaticValue(rightType);
|
|
344
|
+
if (leftStaticValue != null && rightStaticValue != null) {
|
|
345
|
+
const conditionIsTrue = booleanComparison(leftStaticValue.value, operator, rightStaticValue.value);
|
|
346
|
+
context.report({
|
|
347
|
+
node,
|
|
348
|
+
messageId: 'comparisonBetweenLiteralTypes',
|
|
349
|
+
data: {
|
|
350
|
+
left: checker.typeToString(leftType),
|
|
351
|
+
operator,
|
|
352
|
+
right: checker.typeToString(rightType),
|
|
353
|
+
trueOrFalse: conditionIsTrue ? 'true' : 'false',
|
|
354
|
+
},
|
|
355
|
+
});
|
|
356
|
+
return;
|
|
357
|
+
}
|
|
358
|
+
// Workaround for https://github.com/microsoft/TypeScript/issues/37160
|
|
359
|
+
if (isStrictNullChecks) {
|
|
360
|
+
const UNDEFINED = ts.TypeFlags.Undefined;
|
|
361
|
+
const NULL = ts.TypeFlags.Null;
|
|
362
|
+
const VOID = ts.TypeFlags.Void;
|
|
363
|
+
const isComparable = (type, flag) => {
|
|
364
|
+
// Allow comparison to `any`, `unknown` or a naked type parameter.
|
|
365
|
+
flag |=
|
|
366
|
+
ts.TypeFlags.Any |
|
|
367
|
+
ts.TypeFlags.Unknown |
|
|
368
|
+
ts.TypeFlags.TypeParameter |
|
|
369
|
+
ts.TypeFlags.TypeVariable;
|
|
370
|
+
// Allow loose comparison to nullish values.
|
|
371
|
+
if (operator === '==' || operator === '!=') {
|
|
372
|
+
flag |= NULL | UNDEFINED | VOID;
|
|
373
|
+
}
|
|
374
|
+
return (0, util_1.isTypeFlagSet)(type, flag);
|
|
375
|
+
};
|
|
376
|
+
if ((leftType.flags === UNDEFINED &&
|
|
377
|
+
!isComparable(rightType, UNDEFINED | VOID)) ||
|
|
378
|
+
(rightType.flags === UNDEFINED &&
|
|
379
|
+
!isComparable(leftType, UNDEFINED | VOID)) ||
|
|
380
|
+
(leftType.flags === NULL && !isComparable(rightType, NULL)) ||
|
|
381
|
+
(rightType.flags === NULL && !isComparable(leftType, NULL))) {
|
|
382
|
+
context.report({ node, messageId: 'noOverlapBooleanExpression' });
|
|
383
|
+
return;
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
/**
|
|
388
|
+
* Checks that a logical expression contains a boolean, reports otherwise.
|
|
389
|
+
*/
|
|
390
|
+
function checkLogicalExpressionForUnnecessaryConditionals(node) {
|
|
391
|
+
if (node.operator === '??') {
|
|
392
|
+
checkNodeForNullish(node.left);
|
|
393
|
+
return;
|
|
394
|
+
}
|
|
395
|
+
// Only checks the left side, since the right side might not be "conditional" at all.
|
|
396
|
+
// The right side will be checked if the LogicalExpression is used in a conditional context
|
|
397
|
+
checkNode(node.left);
|
|
398
|
+
}
|
|
399
|
+
/**
|
|
400
|
+
* Checks that a testable expression of a loop is necessarily conditional, reports otherwise.
|
|
401
|
+
*/
|
|
402
|
+
function checkIfLoopIsNecessaryConditional(node) {
|
|
403
|
+
if (node.test == null) {
|
|
404
|
+
// e.g. `for(;;)`
|
|
405
|
+
return;
|
|
406
|
+
}
|
|
407
|
+
if (allowConstantLoopConditionsOption === 'only-allowed-literals' &&
|
|
408
|
+
node.test.type === utils_1.AST_NODE_TYPES.Literal &&
|
|
409
|
+
constantLoopConditionsAllowedLiterals.has(node.test.value)) {
|
|
410
|
+
return;
|
|
411
|
+
}
|
|
412
|
+
if (allowConstantLoopConditionsOption === 'always' &&
|
|
413
|
+
tsutils.isTrueLiteralType((0, util_1.getConstrainedTypeAtLocation)(services, node.test))) {
|
|
414
|
+
return;
|
|
415
|
+
}
|
|
416
|
+
checkNode(node.test);
|
|
417
|
+
}
|
|
418
|
+
function checkCallExpression(node) {
|
|
419
|
+
if (checkTypePredicates) {
|
|
420
|
+
const truthinessAssertedArgument = (0, assertionFunctionUtils_1.findTruthinessAssertedArgument)(services, node);
|
|
421
|
+
if (truthinessAssertedArgument != null) {
|
|
422
|
+
checkNode(truthinessAssertedArgument);
|
|
423
|
+
}
|
|
424
|
+
const typeGuardAssertedArgument = (0, assertionFunctionUtils_1.findTypeGuardAssertedArgument)(services, node);
|
|
425
|
+
if (typeGuardAssertedArgument != null) {
|
|
426
|
+
const typeOfArgument = (0, util_1.getConstrainedTypeAtLocation)(services, typeGuardAssertedArgument.argument);
|
|
427
|
+
if (typeOfArgument === typeGuardAssertedArgument.type) {
|
|
428
|
+
context.report({
|
|
429
|
+
node: typeGuardAssertedArgument.argument,
|
|
430
|
+
messageId: 'typeGuardAlreadyIsType',
|
|
431
|
+
data: {
|
|
432
|
+
typeGuardOrAssertionFunction: typeGuardAssertedArgument.asserts
|
|
433
|
+
? 'assertion function'
|
|
434
|
+
: 'type guard',
|
|
435
|
+
},
|
|
436
|
+
});
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
// If this is something like arr.filter(x => /*condition*/), check `condition`
|
|
441
|
+
if ((0, util_1.isArrayMethodCallWithPredicate)(context, services, node) &&
|
|
442
|
+
node.arguments.length) {
|
|
443
|
+
const callback = node.arguments[0];
|
|
444
|
+
// Inline defined functions
|
|
445
|
+
if (callback.type === utils_1.AST_NODE_TYPES.ArrowFunctionExpression ||
|
|
446
|
+
callback.type === utils_1.AST_NODE_TYPES.FunctionExpression) {
|
|
447
|
+
// Two special cases, where we can directly check the node that's returned:
|
|
448
|
+
// () => something
|
|
449
|
+
if (callback.body.type !== utils_1.AST_NODE_TYPES.BlockStatement) {
|
|
450
|
+
return checkNode(callback.body);
|
|
451
|
+
}
|
|
452
|
+
// () => { return something; }
|
|
453
|
+
const callbackBody = callback.body.body;
|
|
454
|
+
if (callbackBody.length === 1 &&
|
|
455
|
+
callbackBody[0].type === utils_1.AST_NODE_TYPES.ReturnStatement &&
|
|
456
|
+
callbackBody[0].argument) {
|
|
457
|
+
return checkNode(callbackBody[0].argument);
|
|
458
|
+
}
|
|
459
|
+
// Potential enhancement: could use code-path analysis to check
|
|
460
|
+
// any function with a single return statement
|
|
461
|
+
// (Value to complexity ratio is dubious however)
|
|
462
|
+
}
|
|
463
|
+
// Otherwise just do type analysis on the function as a whole.
|
|
464
|
+
const returnTypes = tsutils
|
|
465
|
+
.getCallSignaturesOfType((0, util_1.getConstrainedTypeAtLocation)(services, callback))
|
|
466
|
+
.map(sig => sig.getReturnType());
|
|
467
|
+
if (returnTypes.length === 0) {
|
|
468
|
+
// Not a callable function, e.g. `any`
|
|
469
|
+
return;
|
|
470
|
+
}
|
|
471
|
+
let hasFalsyReturnTypes = false;
|
|
472
|
+
let hasTruthyReturnTypes = false;
|
|
473
|
+
for (const type of returnTypes) {
|
|
474
|
+
const { constraintType } = (0, util_1.getConstraintInfo)(checker, type);
|
|
475
|
+
// Predicate is always necessary if it involves `any` or `unknown`
|
|
476
|
+
if (!constraintType ||
|
|
477
|
+
(0, util_1.isTypeAnyType)(constraintType) ||
|
|
478
|
+
(0, util_1.isTypeUnknownType)(constraintType)) {
|
|
479
|
+
return;
|
|
480
|
+
}
|
|
481
|
+
if ((0, util_1.isPossiblyFalsy)(constraintType)) {
|
|
482
|
+
hasFalsyReturnTypes = true;
|
|
483
|
+
}
|
|
484
|
+
if ((0, util_1.isPossiblyTruthy)(constraintType)) {
|
|
485
|
+
hasTruthyReturnTypes = true;
|
|
486
|
+
}
|
|
487
|
+
// bail early if both a possibly-truthy and a possibly-falsy have been detected
|
|
488
|
+
if (hasFalsyReturnTypes && hasTruthyReturnTypes) {
|
|
489
|
+
return;
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
if (!hasFalsyReturnTypes) {
|
|
493
|
+
return context.report({
|
|
494
|
+
node: callback,
|
|
495
|
+
messageId: 'alwaysTruthyFunc',
|
|
496
|
+
});
|
|
497
|
+
}
|
|
498
|
+
if (!hasTruthyReturnTypes) {
|
|
499
|
+
return context.report({
|
|
500
|
+
node: callback,
|
|
501
|
+
messageId: 'alwaysFalsyFunc',
|
|
502
|
+
});
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
// Recursively searches an optional chain for an array index expression
|
|
507
|
+
// Has to search the entire chain, because an array index will "infect" the rest of the types
|
|
508
|
+
// Example:
|
|
509
|
+
// ```
|
|
510
|
+
// [{x: {y: "z"} }][n] // type is {x: {y: "z"}}
|
|
511
|
+
// ?.x // type is {y: "z"}
|
|
512
|
+
// ?.y // This access is considered "unnecessary" according to the types
|
|
513
|
+
// ```
|
|
514
|
+
function optionChainContainsOptionArrayIndex(node) {
|
|
515
|
+
const lhsNode = node.type === utils_1.AST_NODE_TYPES.CallExpression ? node.callee : node.object;
|
|
516
|
+
if (node.optional && isArrayIndexExpression(lhsNode)) {
|
|
517
|
+
return true;
|
|
518
|
+
}
|
|
519
|
+
if (lhsNode.type === utils_1.AST_NODE_TYPES.MemberExpression ||
|
|
520
|
+
lhsNode.type === utils_1.AST_NODE_TYPES.CallExpression) {
|
|
521
|
+
return optionChainContainsOptionArrayIndex(lhsNode);
|
|
522
|
+
}
|
|
523
|
+
return false;
|
|
524
|
+
}
|
|
525
|
+
function isNullablePropertyType(objType, propertyType) {
|
|
526
|
+
if (propertyType.isUnion()) {
|
|
527
|
+
return propertyType.types.some(type => isNullablePropertyType(objType, type));
|
|
528
|
+
}
|
|
529
|
+
if (propertyType.isNumberLiteral() || propertyType.isStringLiteral()) {
|
|
530
|
+
const propType = (0, util_1.getTypeOfPropertyOfName)(checker, objType, propertyType.value.toString());
|
|
531
|
+
if (propType) {
|
|
532
|
+
return (0, util_1.isNullableType)(propType);
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
const typeName = (0, util_1.getTypeName)(checker, propertyType);
|
|
536
|
+
return checker
|
|
537
|
+
.getIndexInfosOfType(objType)
|
|
538
|
+
.some(info => (0, util_1.getTypeName)(checker, info.keyType) === typeName);
|
|
539
|
+
}
|
|
540
|
+
// Checks whether a member expression is nullable or not regardless of it's previous node.
|
|
541
|
+
// Example:
|
|
542
|
+
// ```
|
|
543
|
+
// // 'bar' is nullable if 'foo' is null.
|
|
544
|
+
// // but this function checks regardless of 'foo' type, so returns 'true'.
|
|
545
|
+
// declare const foo: { bar : { baz: string } } | null
|
|
546
|
+
// foo?.bar;
|
|
547
|
+
// ```
|
|
548
|
+
function isMemberExpressionNullableOriginFromObject(node) {
|
|
549
|
+
const prevType = (0, util_1.getConstrainedTypeAtLocation)(services, node.object);
|
|
550
|
+
const property = node.property;
|
|
551
|
+
if (prevType.isUnion() && (0, util_1.isIdentifier)(property)) {
|
|
552
|
+
const isOwnNullable = prevType.types.some(type => {
|
|
553
|
+
if (node.computed) {
|
|
554
|
+
const propertyType = (0, util_1.getConstrainedTypeAtLocation)(services, node.property);
|
|
555
|
+
return isNullablePropertyType(type, propertyType);
|
|
556
|
+
}
|
|
557
|
+
const propType = (0, util_1.getTypeOfPropertyOfName)(checker, type, property.name);
|
|
558
|
+
if (propType) {
|
|
559
|
+
return (0, util_1.isNullableType)(propType);
|
|
560
|
+
}
|
|
561
|
+
const indexInfo = checker.getIndexInfosOfType(type);
|
|
562
|
+
return indexInfo.some(info => {
|
|
563
|
+
const isStringTypeName = (0, util_1.getTypeName)(checker, info.keyType) === 'string';
|
|
564
|
+
return (isStringTypeName &&
|
|
565
|
+
(isNoUncheckedIndexedAccess || (0, util_1.isNullableType)(info.type)));
|
|
566
|
+
});
|
|
567
|
+
});
|
|
568
|
+
return !isOwnNullable && (0, util_1.isNullableType)(prevType);
|
|
569
|
+
}
|
|
570
|
+
return false;
|
|
571
|
+
}
|
|
572
|
+
function isCallExpressionNullableOriginFromCallee(node) {
|
|
573
|
+
const prevType = (0, util_1.getConstrainedTypeAtLocation)(services, node.callee);
|
|
574
|
+
if (prevType.isUnion()) {
|
|
575
|
+
const isOwnNullable = prevType.types.some(type => {
|
|
576
|
+
const signatures = type.getCallSignatures();
|
|
577
|
+
return signatures.some(sig => (0, util_1.isNullableType)(sig.getReturnType()));
|
|
578
|
+
});
|
|
579
|
+
return !isOwnNullable && (0, util_1.isNullableType)(prevType);
|
|
580
|
+
}
|
|
581
|
+
return false;
|
|
582
|
+
}
|
|
583
|
+
function isOptionableExpression(node) {
|
|
584
|
+
const type = (0, util_1.getConstrainedTypeAtLocation)(services, node);
|
|
585
|
+
const isOwnNullable = node.type === utils_1.AST_NODE_TYPES.MemberExpression
|
|
586
|
+
? !isMemberExpressionNullableOriginFromObject(node)
|
|
587
|
+
: node.type === utils_1.AST_NODE_TYPES.CallExpression
|
|
588
|
+
? !isCallExpressionNullableOriginFromCallee(node)
|
|
589
|
+
: true;
|
|
590
|
+
return (isConditionalAlwaysNecessary(type) ||
|
|
591
|
+
(isOwnNullable && (0, util_1.isNullableType)(type)));
|
|
592
|
+
}
|
|
593
|
+
function checkOptionalChain(node, beforeOperator, fix) {
|
|
594
|
+
// We only care if this step in the chain is optional. If just descend
|
|
595
|
+
// from an optional chain, then that's fine.
|
|
596
|
+
if (!node.optional) {
|
|
597
|
+
return;
|
|
598
|
+
}
|
|
599
|
+
// Since typescript array index signature types don't represent the
|
|
600
|
+
// possibility of out-of-bounds access, if we're indexing into an array
|
|
601
|
+
// just skip the check, to avoid false positives
|
|
602
|
+
if (!isNoUncheckedIndexedAccess &&
|
|
603
|
+
optionChainContainsOptionArrayIndex(node)) {
|
|
604
|
+
return;
|
|
605
|
+
}
|
|
606
|
+
const nodeToCheck = node.type === utils_1.AST_NODE_TYPES.CallExpression ? node.callee : node.object;
|
|
607
|
+
if (isOptionableExpression(nodeToCheck)) {
|
|
608
|
+
return;
|
|
609
|
+
}
|
|
610
|
+
const questionDotOperator = (0, util_1.nullThrows)(context.sourceCode.getTokenAfter(beforeOperator, token => token.type === utils_1.AST_TOKEN_TYPES.Punctuator && token.value === '?.'), util_1.NullThrowsReasons.MissingToken('operator', node.type));
|
|
611
|
+
context.report({
|
|
612
|
+
loc: questionDotOperator.loc,
|
|
613
|
+
node,
|
|
614
|
+
messageId: 'neverOptionalChain',
|
|
615
|
+
suggest: [
|
|
616
|
+
{
|
|
617
|
+
messageId: 'suggestRemoveOptionalChain',
|
|
618
|
+
fix(fixer) {
|
|
619
|
+
return fixer.replaceText(questionDotOperator, fix);
|
|
620
|
+
},
|
|
621
|
+
},
|
|
622
|
+
],
|
|
623
|
+
});
|
|
624
|
+
}
|
|
625
|
+
function checkOptionalMemberExpression(node) {
|
|
626
|
+
checkOptionalChain(node, node.object, node.computed ? '' : '.');
|
|
627
|
+
}
|
|
628
|
+
function checkOptionalCallExpression(node) {
|
|
629
|
+
checkOptionalChain(node, node.callee, '');
|
|
630
|
+
}
|
|
631
|
+
function checkAssignmentExpression(node) {
|
|
632
|
+
// Similar to checkLogicalExpressionForUnnecessaryConditionals, since
|
|
633
|
+
// a ||= b is equivalent to a || (a = b)
|
|
634
|
+
if (['&&=', '||='].includes(node.operator)) {
|
|
635
|
+
checkNode(node.left);
|
|
636
|
+
}
|
|
637
|
+
else if (node.operator === '??=') {
|
|
638
|
+
checkNodeForNullish(node.left);
|
|
639
|
+
}
|
|
640
|
+
}
|
|
641
|
+
return {
|
|
642
|
+
AssignmentExpression: checkAssignmentExpression,
|
|
643
|
+
BinaryExpression(node) {
|
|
644
|
+
const { operator } = node;
|
|
645
|
+
if (isBoolOperator(operator)) {
|
|
646
|
+
checkIfBoolExpressionIsNecessaryConditional(node, node.left, node.right, operator);
|
|
647
|
+
}
|
|
648
|
+
},
|
|
649
|
+
CallExpression: checkCallExpression,
|
|
650
|
+
'CallExpression[optional = true]': checkOptionalCallExpression,
|
|
651
|
+
ConditionalExpression: (node) => checkNode(node.test),
|
|
652
|
+
DoWhileStatement: checkIfLoopIsNecessaryConditional,
|
|
653
|
+
ForStatement: checkIfLoopIsNecessaryConditional,
|
|
654
|
+
IfStatement: (node) => checkNode(node.test),
|
|
655
|
+
LogicalExpression: checkLogicalExpressionForUnnecessaryConditionals,
|
|
656
|
+
'MemberExpression[optional = true]': checkOptionalMemberExpression,
|
|
657
|
+
SwitchCase({ parent, test }) {
|
|
658
|
+
// only check `case ...:`, not `default:`
|
|
659
|
+
if (test) {
|
|
660
|
+
checkIfBoolExpressionIsNecessaryConditional(test, parent.discriminant, test, '===');
|
|
661
|
+
}
|
|
662
|
+
},
|
|
663
|
+
WhileStatement: checkIfLoopIsNecessaryConditional,
|
|
664
|
+
};
|
|
665
|
+
},
|
|
666
|
+
});
|
|
667
|
+
function normalizeAllowConstantLoopConditions(allowConstantLoopConditions) {
|
|
668
|
+
if (allowConstantLoopConditions === true) {
|
|
669
|
+
return 'always';
|
|
670
|
+
}
|
|
671
|
+
if (allowConstantLoopConditions === false) {
|
|
672
|
+
return 'never';
|
|
673
|
+
}
|
|
674
|
+
return allowConstantLoopConditions;
|
|
675
|
+
}
|