From 996afdbef98a79d045e7b3aa82a3302e1fe4c138 Mon Sep 17 00:00:00 2001 From: oxc-bot <176400334+oxc-bot@users.noreply.github.com> Date: Sun, 17 Aug 2025 04:11:29 +0000 Subject: [PATCH] Release 1.12.0 --- .../guide/usage/linter/generated-rules.md | 132 ++++++++++++------ .../linter/rules/eslint/prefer-template.md | 63 +++++++++ .../rules/jsx_a11y/tabindex-no-positive.md | 2 +- .../rules/react/jsx-curly-brace-presence.md | 2 +- .../usage/linter/rules/react/jsx-fragments.md | 104 ++++++++++++++ .../linter/rules/typescript/await-thenable.md | 84 +++++++++++ .../rules/typescript/no-array-delete.md | 72 ++++++++++ .../rules/typescript/no-base-to-string.md | 83 +++++++++++ .../no-confusing-void-expression.md | 87 ++++++++++++ .../no-duplicate-type-constituents.md | 85 +++++++++++ .../rules/typescript/no-floating-promises.md | 5 +- .../rules/typescript/no-for-in-array.md | 92 ++++++++++++ .../rules/typescript/no-implied-eval.md | 85 +++++++++++ .../no-meaningless-void-operator.md | 85 +++++++++++ .../rules/typescript/no-misused-promises.md | 2 +- .../rules/typescript/no-misused-spread.md | 87 ++++++++++++ .../linter/rules/typescript/no-mixed-enums.md | 89 ++++++++++++ .../no-redundant-type-constituents.md | 86 ++++++++++++ .../no-unnecessary-boolean-literal-compare.md | 92 ++++++++++++ .../no-unnecessary-template-expression.md | 84 +++++++++++ .../no-unnecessary-type-arguments.md | 97 +++++++++++++ .../no-unnecessary-type-assertion.md | 82 +++++++++++ .../rules/typescript/no-unsafe-argument.md | 85 +++++++++++ .../rules/typescript/no-unsafe-assignment.md | 91 ++++++++++++ .../linter/rules/typescript/no-unsafe-call.md | 83 +++++++++++ .../typescript/no-unsafe-enum-comparison.md | 95 +++++++++++++ .../typescript/no-unsafe-member-access.md | 83 +++++++++++ .../rules/typescript/no-unsafe-return.md | 90 ++++++++++++ .../typescript/no-unsafe-type-assertion.md | 88 ++++++++++++ .../rules/typescript/no-unsafe-unary-minus.md | 91 ++++++++++++ .../non-nullable-type-assertion-style.md | 90 ++++++++++++ .../rules/typescript/only-throw-error.md | 90 ++++++++++++ .../prefer-promise-reject-errors.md | 90 ++++++++++++ .../prefer-reduce-type-parameter.md | 91 ++++++++++++ .../typescript/prefer-return-this-type.md | 110 +++++++++++++++ .../typescript/promise-function-async.md | 102 ++++++++++++++ .../typescript/related-getter-setter-pairs.md | 104 ++++++++++++++ .../typescript/require-array-sort-compare.md | 93 ++++++++++++ .../linter/rules/typescript/require-await.md | 106 ++++++++++++++ .../typescript/restrict-plus-operands.md | 92 ++++++++++++ .../restrict-template-expressions.md | 103 ++++++++++++++ .../linter/rules/typescript/return-await.md | 102 ++++++++++++++ .../typescript/switch-exhaustiveness-check.md | 132 ++++++++++++++++++ .../linter/rules/typescript/unbound-method.md | 121 ++++++++++++++++ .../use-unknown-in-catch-callback-variable.md | 111 +++++++++++++++ .../guide/usage/linter/rules/version.data.js | 2 +- 46 files changed, 3794 insertions(+), 51 deletions(-) create mode 100644 src/docs/guide/usage/linter/rules/eslint/prefer-template.md create mode 100644 src/docs/guide/usage/linter/rules/react/jsx-fragments.md create mode 100644 src/docs/guide/usage/linter/rules/typescript/await-thenable.md create mode 100644 src/docs/guide/usage/linter/rules/typescript/no-array-delete.md create mode 100644 src/docs/guide/usage/linter/rules/typescript/no-base-to-string.md create mode 100644 src/docs/guide/usage/linter/rules/typescript/no-confusing-void-expression.md create mode 100644 src/docs/guide/usage/linter/rules/typescript/no-duplicate-type-constituents.md create mode 100644 src/docs/guide/usage/linter/rules/typescript/no-for-in-array.md create mode 100644 src/docs/guide/usage/linter/rules/typescript/no-implied-eval.md create mode 100644 src/docs/guide/usage/linter/rules/typescript/no-meaningless-void-operator.md create mode 100644 src/docs/guide/usage/linter/rules/typescript/no-misused-spread.md create mode 100644 src/docs/guide/usage/linter/rules/typescript/no-mixed-enums.md create mode 100644 src/docs/guide/usage/linter/rules/typescript/no-redundant-type-constituents.md create mode 100644 src/docs/guide/usage/linter/rules/typescript/no-unnecessary-boolean-literal-compare.md create mode 100644 src/docs/guide/usage/linter/rules/typescript/no-unnecessary-template-expression.md create mode 100644 src/docs/guide/usage/linter/rules/typescript/no-unnecessary-type-arguments.md create mode 100644 src/docs/guide/usage/linter/rules/typescript/no-unnecessary-type-assertion.md create mode 100644 src/docs/guide/usage/linter/rules/typescript/no-unsafe-argument.md create mode 100644 src/docs/guide/usage/linter/rules/typescript/no-unsafe-assignment.md create mode 100644 src/docs/guide/usage/linter/rules/typescript/no-unsafe-call.md create mode 100644 src/docs/guide/usage/linter/rules/typescript/no-unsafe-enum-comparison.md create mode 100644 src/docs/guide/usage/linter/rules/typescript/no-unsafe-member-access.md create mode 100644 src/docs/guide/usage/linter/rules/typescript/no-unsafe-return.md create mode 100644 src/docs/guide/usage/linter/rules/typescript/no-unsafe-type-assertion.md create mode 100644 src/docs/guide/usage/linter/rules/typescript/no-unsafe-unary-minus.md create mode 100644 src/docs/guide/usage/linter/rules/typescript/non-nullable-type-assertion-style.md create mode 100644 src/docs/guide/usage/linter/rules/typescript/only-throw-error.md create mode 100644 src/docs/guide/usage/linter/rules/typescript/prefer-promise-reject-errors.md create mode 100644 src/docs/guide/usage/linter/rules/typescript/prefer-reduce-type-parameter.md create mode 100644 src/docs/guide/usage/linter/rules/typescript/prefer-return-this-type.md create mode 100644 src/docs/guide/usage/linter/rules/typescript/promise-function-async.md create mode 100644 src/docs/guide/usage/linter/rules/typescript/related-getter-setter-pairs.md create mode 100644 src/docs/guide/usage/linter/rules/typescript/require-array-sort-compare.md create mode 100644 src/docs/guide/usage/linter/rules/typescript/require-await.md create mode 100644 src/docs/guide/usage/linter/rules/typescript/restrict-plus-operands.md create mode 100644 src/docs/guide/usage/linter/rules/typescript/restrict-template-expressions.md create mode 100644 src/docs/guide/usage/linter/rules/typescript/return-await.md create mode 100644 src/docs/guide/usage/linter/rules/typescript/switch-exhaustiveness-check.md create mode 100644 src/docs/guide/usage/linter/rules/typescript/unbound-method.md create mode 100644 src/docs/guide/usage/linter/rules/typescript/use-unknown-in-catch-callback-variable.md diff --git a/src/docs/guide/usage/linter/generated-rules.md b/src/docs/guide/usage/linter/generated-rules.md index 6e66906758..4563068e18 100644 --- a/src/docs/guide/usage/linter/generated-rules.md +++ b/src/docs/guide/usage/linter/generated-rules.md @@ -2,8 +2,8 @@ The progress of all rule implementations is tracked [here](https://github.com/oxc-project/oxc/issues/481). -- Total number of rules: 530 -- Rules turned on by default: 88 +- Total number of rules: 570 +- Rules turned on by default: 103 **Legend for 'Fixable?' column:** @@ -13,7 +13,7 @@ The progress of all rule implementations is tracked [here](https://github.com/ox - ⚠️💡: a dangerous suggestion is available for this rule - 🚧: an auto-fix or suggestion is possible, but currently not implemented -## Correctness (178): +## Correctness (193): Code that is outright wrong or useless. @@ -118,7 +118,7 @@ Code that is outright wrong or useless. | [role-has-required-aria-props](/docs/guide/usage/linter/rules/jsx_a11y/role-has-required-aria-props.html) | jsx_a11y | | | | [role-supports-aria-props](/docs/guide/usage/linter/rules/jsx_a11y/role-supports-aria-props.html) | jsx_a11y | | | | [scope](/docs/guide/usage/linter/rules/jsx_a11y/scope.html) | jsx_a11y | | 🛠️ | -| [tabindex-no-positive](/docs/guide/usage/linter/rules/jsx_a11y/tabindex-no-positive.html) | jsx_a11y | | 🚧 | +| [tabindex-no-positive](/docs/guide/usage/linter/rules/jsx_a11y/tabindex-no-positive.html) | jsx_a11y | | ⚠️💡 | | [google-font-display](/docs/guide/usage/linter/rules/nextjs/google-font-display.html) | nextjs | | | | [google-font-preconnect](/docs/guide/usage/linter/rules/nextjs/google-font-preconnect.html) | nextjs | | | | [inline-script-id](/docs/guide/usage/linter/rules/nextjs/inline-script-id.html) | nextjs | | | @@ -171,17 +171,32 @@ Code that is outright wrong or useless. | [no-render-return-value](/docs/guide/usage/linter/rules/react/no-render-return-value.html) | react | | | | [no-string-refs](/docs/guide/usage/linter/rules/react/no-string-refs.html) | react | | | | [void-dom-elements-no-children](/docs/guide/usage/linter/rules/react/void-dom-elements-no-children.html) | react | | | +| [await-thenable](/docs/guide/usage/linter/rules/typescript/await-thenable.html) | typescript | ✅ | 🚧 | +| [no-array-delete](/docs/guide/usage/linter/rules/typescript/no-array-delete.html) | typescript | ✅ | 🚧 | +| [no-base-to-string](/docs/guide/usage/linter/rules/typescript/no-base-to-string.html) | typescript | ✅ | 🚧 | +| [no-confusing-void-expression](/docs/guide/usage/linter/rules/typescript/no-confusing-void-expression.html) | typescript | ✅ | 🚧 | | [no-duplicate-enum-values](/docs/guide/usage/linter/rules/typescript/no-duplicate-enum-values.html) | typescript | ✅ | | +| [no-duplicate-type-constituents](/docs/guide/usage/linter/rules/typescript/no-duplicate-type-constituents.html) | typescript | ✅ | 🚧 | | [no-extra-non-null-assertion](/docs/guide/usage/linter/rules/typescript/no-extra-non-null-assertion.html) | typescript | ✅ | | +| [no-floating-promises](/docs/guide/usage/linter/rules/typescript/no-floating-promises.html) | typescript | ✅ | 🚧 | +| [no-for-in-array](/docs/guide/usage/linter/rules/typescript/no-for-in-array.html) | typescript | ✅ | 🚧 | +| [no-implied-eval](/docs/guide/usage/linter/rules/typescript/no-implied-eval.html) | typescript | ✅ | 🚧 | +| [no-meaningless-void-operator](/docs/guide/usage/linter/rules/typescript/no-meaningless-void-operator.html) | typescript | ✅ | 🚧 | | [no-misused-new](/docs/guide/usage/linter/rules/typescript/no-misused-new.html) | typescript | ✅ | | +| [no-misused-spread](/docs/guide/usage/linter/rules/typescript/no-misused-spread.html) | typescript | ✅ | 🚧 | | [no-non-null-asserted-optional-chain](/docs/guide/usage/linter/rules/typescript/no-non-null-asserted-optional-chain.html) | typescript | ✅ | 🛠️ | +| [no-redundant-type-constituents](/docs/guide/usage/linter/rules/typescript/no-redundant-type-constituents.html) | typescript | ✅ | 🚧 | | [no-this-alias](/docs/guide/usage/linter/rules/typescript/no-this-alias.html) | typescript | ✅ | | | [no-unnecessary-parameter-property-assignment](/docs/guide/usage/linter/rules/typescript/no-unnecessary-parameter-property-assignment.html) | typescript | ✅ | 💡 | | [no-unsafe-declaration-merging](/docs/guide/usage/linter/rules/typescript/no-unsafe-declaration-merging.html) | typescript | ✅ | | +| [no-unsafe-unary-minus](/docs/guide/usage/linter/rules/typescript/no-unsafe-unary-minus.html) | typescript | ✅ | 🚧 | | [no-useless-empty-export](/docs/guide/usage/linter/rules/typescript/no-useless-empty-export.html) | typescript | ✅ | 🛠️ | | [no-wrapper-object-types](/docs/guide/usage/linter/rules/typescript/no-wrapper-object-types.html) | typescript | ✅ | 🛠️ | | [prefer-as-const](/docs/guide/usage/linter/rules/typescript/prefer-as-const.html) | typescript | ✅ | 🛠️ | +| [require-array-sort-compare](/docs/guide/usage/linter/rules/typescript/require-array-sort-compare.html) | typescript | ✅ | 🚧 | +| [restrict-template-expressions](/docs/guide/usage/linter/rules/typescript/restrict-template-expressions.html) | typescript | ✅ | 🚧 | | [triple-slash-reference](/docs/guide/usage/linter/rules/typescript/triple-slash-reference.html) | typescript | ✅ | | +| [unbound-method](/docs/guide/usage/linter/rules/typescript/unbound-method.html) | typescript | ✅ | 🚧 | | [no-await-in-promise-methods](/docs/guide/usage/linter/rules/unicorn/no-await-in-promise-methods.html) | unicorn | ✅ | | | [no-empty-file](/docs/guide/usage/linter/rules/unicorn/no-empty-file.html) | unicorn | ✅ | | | [no-invalid-fetch-options](/docs/guide/usage/linter/rules/unicorn/no-invalid-fetch-options.html) | unicorn | ✅ | | @@ -216,7 +231,7 @@ Code that can be written to run faster. | [prefer-array-flat-map](/docs/guide/usage/linter/rules/unicorn/prefer-array-flat-map.html) | unicorn | | 🛠️ | | [prefer-set-has](/docs/guide/usage/linter/rules/unicorn/prefer-set-has.html) | unicorn | | ⚠️🛠️️ | -## Restriction (67): +## Restriction (70): Lints which prevent the use of language and library features. Must not be enabled as a whole, should be considered on a case-by-case basis before enabling. @@ -277,7 +292,10 @@ Lints which prevent the use of language and library features. Must not be enable | [no-non-null-assertion](/docs/guide/usage/linter/rules/typescript/no-non-null-assertion.html) | typescript | | | | [no-require-imports](/docs/guide/usage/linter/rules/typescript/no-require-imports.html) | typescript | | 🚧 | | [no-var-requires](/docs/guide/usage/linter/rules/typescript/no-var-requires.html) | typescript | | | +| [non-nullable-type-assertion-style](/docs/guide/usage/linter/rules/typescript/non-nullable-type-assertion-style.html) | typescript | | 🚧 | | [prefer-literal-enum-member](/docs/guide/usage/linter/rules/typescript/prefer-literal-enum-member.html) | typescript | | | +| [promise-function-async](/docs/guide/usage/linter/rules/typescript/promise-function-async.html) | typescript | | 🚧 | +| [use-unknown-in-catch-callback-variable](/docs/guide/usage/linter/rules/typescript/use-unknown-in-catch-callback-variable.html) | typescript | | 🚧 | | [no-abusive-eslint-disable](/docs/guide/usage/linter/rules/unicorn/no-abusive-eslint-disable.html) | unicorn | | | | [no-anonymous-default-export](/docs/guide/usage/linter/rules/unicorn/no-anonymous-default-export.html) | unicorn | | | | [no-array-for-each](/docs/guide/usage/linter/rules/unicorn/no-array-for-each.html) | unicorn | | 🚧 | @@ -290,49 +308,53 @@ Lints which prevent the use of language and library features. Must not be enable | [prefer-node-protocol](/docs/guide/usage/linter/rules/unicorn/prefer-node-protocol.html) | unicorn | | 🛠️ | | [prefer-number-properties](/docs/guide/usage/linter/rules/unicorn/prefer-number-properties.html) | unicorn | | ⚠️🛠️️ | -## Suspicious (35): +## Suspicious (39): code that is most likely wrong or useless. -| Rule name | Source | Default | Fixable? | -| -------------------------------------------------------------------------------------------------------------------- | ---------- | ------- | -------- | -| [block-scoped-var](/docs/guide/usage/linter/rules/eslint/block-scoped-var.html) | eslint | | | -| [no-extend-native](/docs/guide/usage/linter/rules/eslint/no-extend-native.html) | eslint | | | -| [no-extra-bind](/docs/guide/usage/linter/rules/eslint/no-extra-bind.html) | eslint | | 🚧 | -| [no-new](/docs/guide/usage/linter/rules/eslint/no-new.html) | eslint | | | -| [no-unexpected-multiline](/docs/guide/usage/linter/rules/eslint/no-unexpected-multiline.html) | eslint | | ⚠️🛠️️ | -| [no-unneeded-ternary](/docs/guide/usage/linter/rules/eslint/no-unneeded-ternary.html) | eslint | | ⚠️🛠️️ | -| [no-useless-concat](/docs/guide/usage/linter/rules/eslint/no-useless-concat.html) | eslint | | | -| [no-useless-constructor](/docs/guide/usage/linter/rules/eslint/no-useless-constructor.html) | eslint | | 🛠️ | -| [no-absolute-path](/docs/guide/usage/linter/rules/import/no-absolute-path.html) | import | | 🚧 | -| [no-empty-named-blocks](/docs/guide/usage/linter/rules/import/no-empty-named-blocks.html) | import | | 🛠️ | -| [no-named-as-default](/docs/guide/usage/linter/rules/import/no-named-as-default.html) | import | | | -| [no-named-as-default-member](/docs/guide/usage/linter/rules/import/no-named-as-default-member.html) | import | | | -| [no-self-import](/docs/guide/usage/linter/rules/import/no-self-import.html) | import | | | -| [no-unassigned-import](/docs/guide/usage/linter/rules/import/no-unassigned-import.html) | import | | | -| [no-commented-out-tests](/docs/guide/usage/linter/rules/jest/no-commented-out-tests.html) | jest | | | -| [approx-constant](/docs/guide/usage/linter/rules/oxc/approx-constant.html) | oxc | | | -| [misrefactored-assign-op](/docs/guide/usage/linter/rules/oxc/misrefactored-assign-op.html) | oxc | | 🚧 | -| [no-async-endpoint-handlers](/docs/guide/usage/linter/rules/oxc/no-async-endpoint-handlers.html) | oxc | | | -| [no-promise-in-callback](/docs/guide/usage/linter/rules/promise/no-promise-in-callback.html) | promise | | | -| [iframe-missing-sandbox](/docs/guide/usage/linter/rules/react/iframe-missing-sandbox.html) | react | | 🚧 | -| [jsx-no-comment-textnodes](/docs/guide/usage/linter/rules/react/jsx-no-comment-textnodes.html) | react | | | -| [jsx-no-script-url](/docs/guide/usage/linter/rules/react/jsx-no-script-url.html) | react | | 🚧 | -| [no-namespace](/docs/guide/usage/linter/rules/react/no-namespace.html) | react | | | -| [react-in-jsx-scope](/docs/guide/usage/linter/rules/react/react-in-jsx-scope.html) | react | | | -| [style-prop-object](/docs/guide/usage/linter/rules/react/style-prop-object.html) | react | | | -| [no-confusing-non-null-assertion](/docs/guide/usage/linter/rules/typescript/no-confusing-non-null-assertion.html) | typescript | | 🚧 | -| [no-extraneous-class](/docs/guide/usage/linter/rules/typescript/no-extraneous-class.html) | typescript | | ⚠️💡 | -| [no-floating-promises](/docs/guide/usage/linter/rules/typescript/no-floating-promises.html) | typescript | | 🚧 | -| [no-misused-promises](/docs/guide/usage/linter/rules/typescript/no-misused-promises.html) | typescript | | 🚧 | -| [no-unnecessary-type-constraint](/docs/guide/usage/linter/rules/typescript/no-unnecessary-type-constraint.html) | typescript | | | -| [consistent-function-scoping](/docs/guide/usage/linter/rules/unicorn/consistent-function-scoping.html) | unicorn | | 🚧 | -| [no-accessor-recursion](/docs/guide/usage/linter/rules/unicorn/no-accessor-recursion.html) | unicorn | | | -| [no-instanceof-builtins](/docs/guide/usage/linter/rules/unicorn/no-instanceof-builtins.html) | unicorn | | 🚧 | -| [prefer-add-event-listener](/docs/guide/usage/linter/rules/unicorn/prefer-add-event-listener.html) | unicorn | | 🚧 | -| [require-post-message-target-origin](/docs/guide/usage/linter/rules/unicorn/require-post-message-target-origin.html) | unicorn | | 💡 | +| Rule name | Source | Default | Fixable? | +| ------------------------------------------------------------------------------------------------------------------------------- | ---------- | ------- | -------- | +| [block-scoped-var](/docs/guide/usage/linter/rules/eslint/block-scoped-var.html) | eslint | | | +| [no-extend-native](/docs/guide/usage/linter/rules/eslint/no-extend-native.html) | eslint | | | +| [no-extra-bind](/docs/guide/usage/linter/rules/eslint/no-extra-bind.html) | eslint | | 🚧 | +| [no-new](/docs/guide/usage/linter/rules/eslint/no-new.html) | eslint | | | +| [no-unexpected-multiline](/docs/guide/usage/linter/rules/eslint/no-unexpected-multiline.html) | eslint | | ⚠️🛠️️ | +| [no-unneeded-ternary](/docs/guide/usage/linter/rules/eslint/no-unneeded-ternary.html) | eslint | | ⚠️🛠️️ | +| [no-useless-concat](/docs/guide/usage/linter/rules/eslint/no-useless-concat.html) | eslint | | | +| [no-useless-constructor](/docs/guide/usage/linter/rules/eslint/no-useless-constructor.html) | eslint | | 🛠️ | +| [no-absolute-path](/docs/guide/usage/linter/rules/import/no-absolute-path.html) | import | | 🚧 | +| [no-empty-named-blocks](/docs/guide/usage/linter/rules/import/no-empty-named-blocks.html) | import | | 🛠️ | +| [no-named-as-default](/docs/guide/usage/linter/rules/import/no-named-as-default.html) | import | | | +| [no-named-as-default-member](/docs/guide/usage/linter/rules/import/no-named-as-default-member.html) | import | | | +| [no-self-import](/docs/guide/usage/linter/rules/import/no-self-import.html) | import | | | +| [no-unassigned-import](/docs/guide/usage/linter/rules/import/no-unassigned-import.html) | import | | | +| [no-commented-out-tests](/docs/guide/usage/linter/rules/jest/no-commented-out-tests.html) | jest | | | +| [approx-constant](/docs/guide/usage/linter/rules/oxc/approx-constant.html) | oxc | | | +| [misrefactored-assign-op](/docs/guide/usage/linter/rules/oxc/misrefactored-assign-op.html) | oxc | | 🚧 | +| [no-async-endpoint-handlers](/docs/guide/usage/linter/rules/oxc/no-async-endpoint-handlers.html) | oxc | | | +| [no-promise-in-callback](/docs/guide/usage/linter/rules/promise/no-promise-in-callback.html) | promise | | | +| [iframe-missing-sandbox](/docs/guide/usage/linter/rules/react/iframe-missing-sandbox.html) | react | | 🚧 | +| [jsx-no-comment-textnodes](/docs/guide/usage/linter/rules/react/jsx-no-comment-textnodes.html) | react | | | +| [jsx-no-script-url](/docs/guide/usage/linter/rules/react/jsx-no-script-url.html) | react | | 🚧 | +| [no-namespace](/docs/guide/usage/linter/rules/react/no-namespace.html) | react | | | +| [react-in-jsx-scope](/docs/guide/usage/linter/rules/react/react-in-jsx-scope.html) | react | | | +| [style-prop-object](/docs/guide/usage/linter/rules/react/style-prop-object.html) | react | | | +| [no-confusing-non-null-assertion](/docs/guide/usage/linter/rules/typescript/no-confusing-non-null-assertion.html) | typescript | | 🚧 | +| [no-extraneous-class](/docs/guide/usage/linter/rules/typescript/no-extraneous-class.html) | typescript | | ⚠️💡 | +| [no-unnecessary-boolean-literal-compare](/docs/guide/usage/linter/rules/typescript/no-unnecessary-boolean-literal-compare.html) | typescript | | 🚧 | +| [no-unnecessary-template-expression](/docs/guide/usage/linter/rules/typescript/no-unnecessary-template-expression.html) | typescript | | 🚧 | +| [no-unnecessary-type-arguments](/docs/guide/usage/linter/rules/typescript/no-unnecessary-type-arguments.html) | typescript | | 🚧 | +| [no-unnecessary-type-assertion](/docs/guide/usage/linter/rules/typescript/no-unnecessary-type-assertion.html) | typescript | | 🚧 | +| [no-unnecessary-type-constraint](/docs/guide/usage/linter/rules/typescript/no-unnecessary-type-constraint.html) | typescript | | | +| [no-unsafe-enum-comparison](/docs/guide/usage/linter/rules/typescript/no-unsafe-enum-comparison.html) | typescript | | 🚧 | +| [no-unsafe-type-assertion](/docs/guide/usage/linter/rules/typescript/no-unsafe-type-assertion.html) | typescript | | 🚧 | +| [consistent-function-scoping](/docs/guide/usage/linter/rules/unicorn/consistent-function-scoping.html) | unicorn | | 🚧 | +| [no-accessor-recursion](/docs/guide/usage/linter/rules/unicorn/no-accessor-recursion.html) | unicorn | | | +| [no-instanceof-builtins](/docs/guide/usage/linter/rules/unicorn/no-instanceof-builtins.html) | unicorn | | 🚧 | +| [prefer-add-event-listener](/docs/guide/usage/linter/rules/unicorn/prefer-add-event-listener.html) | unicorn | | 🚧 | +| [require-post-message-target-origin](/docs/guide/usage/linter/rules/unicorn/require-post-message-target-origin.html) | unicorn | | 💡 | -## Pedantic (82): +## Pedantic (96): Lints which are rather strict or have occasional false positives. @@ -378,9 +400,23 @@ Lints which are rather strict or have occasional false positives. | [rules-of-hooks](/docs/guide/usage/linter/rules/react/rules-of-hooks.html) | react | | | | [ban-ts-comment](/docs/guide/usage/linter/rules/typescript/ban-ts-comment.html) | typescript | | 🛠️ | | [ban-types](/docs/guide/usage/linter/rules/typescript/ban-types.html) | typescript | | 🚧 | +| [no-misused-promises](/docs/guide/usage/linter/rules/typescript/no-misused-promises.html) | typescript | | 🚧 | +| [no-mixed-enums](/docs/guide/usage/linter/rules/typescript/no-mixed-enums.html) | typescript | | 🚧 | +| [no-unsafe-argument](/docs/guide/usage/linter/rules/typescript/no-unsafe-argument.html) | typescript | | 🚧 | +| [no-unsafe-assignment](/docs/guide/usage/linter/rules/typescript/no-unsafe-assignment.html) | typescript | | 🚧 | +| [no-unsafe-call](/docs/guide/usage/linter/rules/typescript/no-unsafe-call.html) | typescript | | 🚧 | | [no-unsafe-function-type](/docs/guide/usage/linter/rules/typescript/no-unsafe-function-type.html) | typescript | | | +| [no-unsafe-member-access](/docs/guide/usage/linter/rules/typescript/no-unsafe-member-access.html) | typescript | | 🚧 | +| [no-unsafe-return](/docs/guide/usage/linter/rules/typescript/no-unsafe-return.html) | typescript | | 🚧 | +| [only-throw-error](/docs/guide/usage/linter/rules/typescript/only-throw-error.html) | typescript | | 🚧 | | [prefer-enum-initializers](/docs/guide/usage/linter/rules/typescript/prefer-enum-initializers.html) | typescript | | 🚧 | +| [prefer-promise-reject-errors](/docs/guide/usage/linter/rules/typescript/prefer-promise-reject-errors.html) | typescript | | 🚧 | | [prefer-ts-expect-error](/docs/guide/usage/linter/rules/typescript/prefer-ts-expect-error.html) | typescript | | 🛠️ | +| [related-getter-setter-pairs](/docs/guide/usage/linter/rules/typescript/related-getter-setter-pairs.html) | typescript | | 🚧 | +| [require-await](/docs/guide/usage/linter/rules/typescript/require-await.html) | typescript | | 🚧 | +| [restrict-plus-operands](/docs/guide/usage/linter/rules/typescript/restrict-plus-operands.html) | typescript | | 🚧 | +| [return-await](/docs/guide/usage/linter/rules/typescript/return-await.html) | typescript | | 🚧 | +| [switch-exhaustiveness-check](/docs/guide/usage/linter/rules/typescript/switch-exhaustiveness-check.html) | typescript | | 🚧 | | [consistent-assert](/docs/guide/usage/linter/rules/unicorn/consistent-assert.html) | unicorn | | 🛠️ | | [consistent-empty-array-spread](/docs/guide/usage/linter/rules/unicorn/consistent-empty-array-spread.html) | unicorn | | 💡 | | [escape-case](/docs/guide/usage/linter/rules/unicorn/escape-case.html) | unicorn | | 🛠️ | @@ -421,7 +457,7 @@ Lints which are rather strict or have occasional false positives. | [prefer-type-error](/docs/guide/usage/linter/rules/unicorn/prefer-type-error.html) | unicorn | | 🛠️ | | [require-number-to-fixed-digits-argument](/docs/guide/usage/linter/rules/unicorn/require-number-to-fixed-digits-argument.html) | unicorn | | 🛠️ | -## Style (149): +## Style (153): Code that should be written in a more idiomatic way. @@ -463,6 +499,7 @@ Code that should be written in a more idiomatic way. | [prefer-promise-reject-errors](/docs/guide/usage/linter/rules/eslint/prefer-promise-reject-errors.html) | eslint | | | | [prefer-rest-params](/docs/guide/usage/linter/rules/eslint/prefer-rest-params.html) | eslint | | | | [prefer-spread](/docs/guide/usage/linter/rules/eslint/prefer-spread.html) | eslint | | | +| [prefer-template](/docs/guide/usage/linter/rules/eslint/prefer-template.html) | eslint | | 🚧 | | [sort-imports](/docs/guide/usage/linter/rules/eslint/sort-imports.html) | eslint | | 🛠️ | | [sort-keys](/docs/guide/usage/linter/rules/eslint/sort-keys.html) | eslint | | 🚧 | | [vars-on-top](/docs/guide/usage/linter/rules/eslint/vars-on-top.html) | eslint | | | @@ -523,7 +560,8 @@ Code that should be written in a more idiomatic way. | [prefer-await-to-then](/docs/guide/usage/linter/rules/promise/prefer-await-to-then.html) | promise | | | | [prefer-catch](/docs/guide/usage/linter/rules/promise/prefer-catch.html) | promise | | 🚧 | | [jsx-boolean-value](/docs/guide/usage/linter/rules/react/jsx-boolean-value.html) | react | | 🛠️ | -| [jsx-curly-brace-presence](/docs/guide/usage/linter/rules/react/jsx-curly-brace-presence.html) | react | | 🚧 | +| [jsx-curly-brace-presence](/docs/guide/usage/linter/rules/react/jsx-curly-brace-presence.html) | react | | 🛠️ | +| [jsx-fragments](/docs/guide/usage/linter/rules/react/jsx-fragments.html) | react | | 🛠️ | | [no-set-state](/docs/guide/usage/linter/rules/react/no-set-state.html) | react | | | | [prefer-es6-class](/docs/guide/usage/linter/rules/react/prefer-es6-class.html) | react | | | | [self-closing-comp](/docs/guide/usage/linter/rules/react/self-closing-comp.html) | react | | 🛠️ | @@ -539,6 +577,8 @@ Code that should be written in a more idiomatic way. | [prefer-for-of](/docs/guide/usage/linter/rules/typescript/prefer-for-of.html) | typescript | | 🚧 | | [prefer-function-type](/docs/guide/usage/linter/rules/typescript/prefer-function-type.html) | typescript | | 🛠️ | | [prefer-namespace-keyword](/docs/guide/usage/linter/rules/typescript/prefer-namespace-keyword.html) | typescript | | 🛠️ | +| [prefer-reduce-type-parameter](/docs/guide/usage/linter/rules/typescript/prefer-reduce-type-parameter.html) | typescript | | 🚧 | +| [prefer-return-this-type](/docs/guide/usage/linter/rules/typescript/prefer-return-this-type.html) | typescript | | 🚧 | | [catch-error-name](/docs/guide/usage/linter/rules/unicorn/catch-error-name.html) | unicorn | | 🛠️ | | [consistent-date-clone](/docs/guide/usage/linter/rules/unicorn/consistent-date-clone.html) | unicorn | | 🛠️ | | [consistent-existence-index-check](/docs/guide/usage/linter/rules/unicorn/consistent-existence-index-check.html) | unicorn | | 🛠️ | diff --git a/src/docs/guide/usage/linter/rules/eslint/prefer-template.md b/src/docs/guide/usage/linter/rules/eslint/prefer-template.md new file mode 100644 index 0000000000..ae5839107b --- /dev/null +++ b/src/docs/guide/usage/linter/rules/eslint/prefer-template.md @@ -0,0 +1,63 @@ + + + + +# eslint/prefer-template + +
+ +🚧 An auto-fix is still under development. + +
+ +### What it does + +Require template literals instead of string concatenation. + +### Why is this bad? + +In ES2015 (ES6), we can use template literals instead of string concatenation. + +### Examples + +Examples of **incorrect** code for this rule: + +```js +const str = "Hello, " + name + "!"; +const str1 = "Time: " + (12 * 60 * 60 * 1000); +``` + +Examples of **correct** code for this rule: + +```js +const str = "Hello World!"; +const str2 = `Time: ${12 * 60 * 60 * 1000}`; +const str4 = "Hello, " + "World!"; +``` + +## How to use + +To **enable** this rule in the CLI or using the config file, you can use: + +::: code-group + +```bash [CLI] +oxlint --deny prefer-template +``` + +```json [Config (.oxlintrc.json)] +{ + "rules": { + "prefer-template": "error" + } +} +``` + +::: + +## References + +- Rule Source diff --git a/src/docs/guide/usage/linter/rules/jsx_a11y/tabindex-no-positive.md b/src/docs/guide/usage/linter/rules/jsx_a11y/tabindex-no-positive.md index 6cc759cce4..ac7989a86b 100644 --- a/src/docs/guide/usage/linter/rules/jsx_a11y/tabindex-no-positive.md +++ b/src/docs/guide/usage/linter/rules/jsx_a11y/tabindex-no-positive.md @@ -9,7 +9,7 @@ const source = `https://github.com/oxc-project/oxc/blob/${ data }/crates/oxc_lin
-🚧 An auto-fix is still under development. +⚠️💡 A dangerous suggestion is available for this rule.
diff --git a/src/docs/guide/usage/linter/rules/react/jsx-curly-brace-presence.md b/src/docs/guide/usage/linter/rules/react/jsx-curly-brace-presence.md index 477359c7c4..5cefdf621c 100644 --- a/src/docs/guide/usage/linter/rules/react/jsx-curly-brace-presence.md +++ b/src/docs/guide/usage/linter/rules/react/jsx-curly-brace-presence.md @@ -9,7 +9,7 @@ const source = `https://github.com/oxc-project/oxc/blob/${ data }/crates/oxc_lin
-🚧 An auto-fix is still under development. +🛠️ An auto-fix is available for this rule.
diff --git a/src/docs/guide/usage/linter/rules/react/jsx-fragments.md b/src/docs/guide/usage/linter/rules/react/jsx-fragments.md new file mode 100644 index 0000000000..ebf0200016 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/react/jsx-fragments.md @@ -0,0 +1,104 @@ + + + + +# react/jsx-fragments + +
+ +🛠️ An auto-fix is available for this rule. + +
+ +### What it does + +Enforces the shorthand or standard form for React Fragments. + +### Why is this bad? + +Makes code using fragments more consistent one way or the other. + +### Options + +`{ "mode": "syntax" | "element" }` + +#### `syntax` mode + +This is the default mode. It will enforce the shorthand syntax for React fragments, with one exception. +Keys or attributes are not supported by the shorthand syntax, so the rule will not warn on standard-form fragments that use those. + +Examples of **incorrect** code for this rule: + +```jsx + + +; +``` + +Examples of **correct** code for this rule: + +```jsx +<> + +; +``` + +```jsx + + +; +``` + +#### `element` mode + +This mode enforces the standard form for React fragments. + +Examples of **incorrect** code for this rule: + +```jsx +<> + +; +``` + +Examples of **correct** code for this rule: + +```jsx + + +; +``` + +```jsx + + +; +``` + +## How to use + +To **enable** this rule in the CLI or using the config file, you can use: + +::: code-group + +```bash [CLI] +oxlint --deny react/jsx-fragments --react-plugin +``` + +```json [Config (.oxlintrc.json)] +{ + "plugins": ["react"], + "rules": { + "react/jsx-fragments": "error" + } +} +``` + +::: + +## References + +- Rule Source diff --git a/src/docs/guide/usage/linter/rules/typescript/await-thenable.md b/src/docs/guide/usage/linter/rules/typescript/await-thenable.md new file mode 100644 index 0000000000..40c729d036 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/typescript/await-thenable.md @@ -0,0 +1,84 @@ + + + + +# typescript/await-thenable + +
+ + This rule is turned on by default. + + +🚧 An auto-fix is still under development. + +
+ +### What it does + +This rule disallows awaiting a value that is not a Thenable. + +### Why is this bad? + +While it is valid JavaScript to await a non-Promise-like value (it will resolve immediately), this practice can be confusing for readers who are not aware of this behavior. It can also be a sign of a programmer error, such as forgetting to add parentheses to call a function that returns a Promise. + +### Examples + +Examples of **incorrect** code for this rule: + +```ts +await 12; +await (() => {}); + +// non-Promise values +await Math.random; +await { then() {} }; + +// this is not a Promise - it's a function that returns a Promise +declare const getPromise: () => Promise; +await getPromise; +``` + +Examples of **correct** code for this rule: + +```ts +await Promise.resolve("value"); +await Promise.reject(new Error()); + +// Promise-like values +await { + then(onfulfilled, onrejected) { + onfulfilled("value"); + }, +}; + +// this is a Promise - produced by calling a function +declare const getPromise: () => Promise; +await getPromise(); +``` + +## How to use + +To **enable** this rule in the CLI or using the config file, you can use: + +::: code-group + +```bash [CLI] +oxlint --deny typescript/await-thenable +``` + +```json [Config (.oxlintrc.json)] +{ + "rules": { + "typescript/await-thenable": "error" + } +} +``` + +::: + +## References + +- Rule Source diff --git a/src/docs/guide/usage/linter/rules/typescript/no-array-delete.md b/src/docs/guide/usage/linter/rules/typescript/no-array-delete.md new file mode 100644 index 0000000000..ae609f28fe --- /dev/null +++ b/src/docs/guide/usage/linter/rules/typescript/no-array-delete.md @@ -0,0 +1,72 @@ + + + + +# typescript/no-array-delete + +
+ + This rule is turned on by default. + + +🚧 An auto-fix is still under development. + +
+ +### What it does + +This rule disallows using the delete operator on array values. + +### Why is this bad? + +When using the delete operator on an array, the element is not actually removed, but instead the array slot is turned into undefined. This is usually not the intended behavior. Instead, you should use methods like Array.prototype.splice() to properly remove elements from an array. + +### Examples + +Examples of **incorrect** code for this rule: + +```ts +declare const arr: number[]; +delete arr[0]; +``` + +Examples of **correct** code for this rule: + +```ts +declare const arr: number[]; +arr.splice(0, 1); + +// or with a filter +const filteredArr = arr.filter((_, index) => index !== 0); + +// delete on object is allowed +declare const obj: { a?: number }; +delete obj.a; +``` + +## How to use + +To **enable** this rule in the CLI or using the config file, you can use: + +::: code-group + +```bash [CLI] +oxlint --deny typescript/no-array-delete +``` + +```json [Config (.oxlintrc.json)] +{ + "rules": { + "typescript/no-array-delete": "error" + } +} +``` + +::: + +## References + +- Rule Source diff --git a/src/docs/guide/usage/linter/rules/typescript/no-base-to-string.md b/src/docs/guide/usage/linter/rules/typescript/no-base-to-string.md new file mode 100644 index 0000000000..aa56a2d886 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/typescript/no-base-to-string.md @@ -0,0 +1,83 @@ + + + + +# typescript/no-base-to-string + +
+ + This rule is turned on by default. + + +🚧 An auto-fix is still under development. + +
+ +### What it does + +This rule requires toString() and toLocaleString() calls to only be called on objects which provide useful information when stringified. + +### Why is this bad? + +JavaScript's toString() method returns '[object Object]' on plain objects, which is not useful information. This rule prevents toString() and toLocaleString() from being called on objects that return less useful strings. + +### Examples + +Examples of **incorrect** code for this rule: + +```ts +// These will evaluate to '[object Object]' +({}).toString(); +({ foo: "bar" }).toString(); +({ foo: "bar" }).toLocaleString(); + +// This will evaluate to 'Symbol()' +Symbol("foo").toString(); +``` + +Examples of **correct** code for this rule: + +```ts +const someString = "Hello world"; +someString.toString(); + +const someNumber = 42; +someNumber.toString(); + +const someBoolean = true; +someBoolean.toString(); + +class CustomToString { + toString() { + return "CustomToString"; + } +} +new CustomToString().toString(); +``` + +## How to use + +To **enable** this rule in the CLI or using the config file, you can use: + +::: code-group + +```bash [CLI] +oxlint --deny typescript/no-base-to-string +``` + +```json [Config (.oxlintrc.json)] +{ + "rules": { + "typescript/no-base-to-string": "error" + } +} +``` + +::: + +## References + +- Rule Source diff --git a/src/docs/guide/usage/linter/rules/typescript/no-confusing-void-expression.md b/src/docs/guide/usage/linter/rules/typescript/no-confusing-void-expression.md new file mode 100644 index 0000000000..4621f8e541 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/typescript/no-confusing-void-expression.md @@ -0,0 +1,87 @@ + + + + +# typescript/no-confusing-void-expression + +
+ + This rule is turned on by default. + + +🚧 An auto-fix is still under development. + +
+ +### What it does + +This rule forbids using void expressions in confusing locations such as arrow function returns. + +### Why is this bad? + +The void operator is useful when you want to execute an expression while evaluating to undefined. However, it can be confusing when used in places where the return value is meaningful, particularly in arrow functions and conditional expressions. + +### Examples + +Examples of **incorrect** code for this rule: + +```ts +// arrow function returning void expression +const foo = () => void bar(); + +// conditional expression +const result = condition ? void foo() : bar(); + +// void in conditional +if (void foo()) { + // ... +} +``` + +Examples of **correct** code for this rule: + +```ts +// proper use of void +void foo(); + +// explicit return statement +const foo = () => { + bar(); + return; +}; + +// statement expression +foo(); + +// IIFE with void +void (function() { + console.log("immediately invoked"); +})(); +``` + +## How to use + +To **enable** this rule in the CLI or using the config file, you can use: + +::: code-group + +```bash [CLI] +oxlint --deny typescript/no-confusing-void-expression +``` + +```json [Config (.oxlintrc.json)] +{ + "rules": { + "typescript/no-confusing-void-expression": "error" + } +} +``` + +::: + +## References + +- Rule Source diff --git a/src/docs/guide/usage/linter/rules/typescript/no-duplicate-type-constituents.md b/src/docs/guide/usage/linter/rules/typescript/no-duplicate-type-constituents.md new file mode 100644 index 0000000000..a2246ffb01 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/typescript/no-duplicate-type-constituents.md @@ -0,0 +1,85 @@ + + + + +# typescript/no-duplicate-type-constituents + +
+ + This rule is turned on by default. + + +🚧 An auto-fix is still under development. + +
+ +### What it does + +This rule disallows duplicate constituents of union or intersection types. + +### Why is this bad? + +Duplicate constituents in union and intersection types serve no purpose and can make code harder to read. They are likely a mistake. + +### Examples + +Examples of **incorrect** code for this rule: + +```ts +type T1 = "A" | "A"; + +type T2 = A | A | B; + +type T3 = { a: string } & { a: string }; + +type T4 = [A, A]; + +type T5 = + | "foo" + | "bar" + | "foo"; +``` + +Examples of **correct** code for this rule: + +```ts +type T1 = "A" | "B"; + +type T2 = A | B | C; + +type T3 = { a: string } & { b: string }; + +type T4 = [A, B]; + +type T5 = + | "foo" + | "bar" + | "baz"; +``` + +## How to use + +To **enable** this rule in the CLI or using the config file, you can use: + +::: code-group + +```bash [CLI] +oxlint --deny typescript/no-duplicate-type-constituents +``` + +```json [Config (.oxlintrc.json)] +{ + "rules": { + "typescript/no-duplicate-type-constituents": "error" + } +} +``` + +::: + +## References + +- Rule Source diff --git a/src/docs/guide/usage/linter/rules/typescript/no-floating-promises.md b/src/docs/guide/usage/linter/rules/typescript/no-floating-promises.md index 829bd55c65..c80fd51f24 100644 --- a/src/docs/guide/usage/linter/rules/typescript/no-floating-promises.md +++ b/src/docs/guide/usage/linter/rules/typescript/no-floating-promises.md @@ -5,9 +5,12 @@ import { data } from '../version.data.js'; const source = `https://github.com/oxc-project/oxc/blob/${ data }/crates/oxc_linter/src/rules/typescript/no_floating_promises.rs`; -# typescript/no-floating-promises +# typescript/no-floating-promises
+ + This rule is turned on by default. + 🚧 An auto-fix is still under development. diff --git a/src/docs/guide/usage/linter/rules/typescript/no-for-in-array.md b/src/docs/guide/usage/linter/rules/typescript/no-for-in-array.md new file mode 100644 index 0000000000..ef91ab3747 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/typescript/no-for-in-array.md @@ -0,0 +1,92 @@ + + + + +# typescript/no-for-in-array + +
+ + This rule is turned on by default. + + +🚧 An auto-fix is still under development. + +
+ +### What it does + +This rule disallows iterating over an array with a for-in loop. + +### Why is this bad? + +A for-in loop iterates over the enumerable properties of an object, which includes the array indices, but also includes any enumerable properties added to the array prototype or the array instance. This is almost never what you want when iterating over an array. + +### Examples + +Examples of **incorrect** code for this rule: + +```ts +const arr = [1, 2, 3]; + +for (const i in arr) { + console.log(arr[i]); +} + +for (const i in arr) { + console.log(i, arr[i]); +} +``` + +Examples of **correct** code for this rule: + +```ts +const arr = [1, 2, 3]; + +// Use for-of to iterate over array values +for (const value of arr) { + console.log(value); +} + +// Use regular for loop with index +for (let i = 0; i < arr.length; i++) { + console.log(i, arr[i]); +} + +// Use forEach +arr.forEach((value, index) => { + console.log(index, value); +}); + +// for-in is fine for objects +const obj = { a: 1, b: 2 }; +for (const key in obj) { + console.log(key, obj[key]); +} +``` + +## How to use + +To **enable** this rule in the CLI or using the config file, you can use: + +::: code-group + +```bash [CLI] +oxlint --deny typescript/no-for-in-array +``` + +```json [Config (.oxlintrc.json)] +{ + "rules": { + "typescript/no-for-in-array": "error" + } +} +``` + +::: + +## References + +- Rule Source diff --git a/src/docs/guide/usage/linter/rules/typescript/no-implied-eval.md b/src/docs/guide/usage/linter/rules/typescript/no-implied-eval.md new file mode 100644 index 0000000000..6e4d497796 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/typescript/no-implied-eval.md @@ -0,0 +1,85 @@ + + + + +# typescript/no-implied-eval + +
+ + This rule is turned on by default. + + +🚧 An auto-fix is still under development. + +
+ +### What it does + +This rule disallows the use of eval-like methods. + +### Why is this bad? + +It's considered a good practice to avoid using eval() in JavaScript. There are security and performance implications involved with doing so, which is why many linters recommend disallowing eval(). However, there are some other ways to pass a string and have it interpreted as JavaScript code that have similar concerns. + +### Examples + +Examples of **incorrect** code for this rule: + +```ts +setTimeout("alert(\"Hi!\");", 100); + +setInterval("alert(\"Hi!\");", 100); + +setImmediate("alert(\"Hi!\")"); + +window.setTimeout("count = 5", 10); + +window.setInterval("foo = bar", 10); + +const fn = new Function("a", "b", "return a + b"); +``` + +Examples of **correct** code for this rule: + +```ts +setTimeout(() => { + alert("Hi!"); +}, 100); + +setInterval(() => { + alert("Hi!"); +}, 100); + +setImmediate(() => { + alert("Hi!"); +}); + +const fn = (a: number, b: number) => a + b; +``` + +## How to use + +To **enable** this rule in the CLI or using the config file, you can use: + +::: code-group + +```bash [CLI] +oxlint --deny typescript/no-implied-eval +``` + +```json [Config (.oxlintrc.json)] +{ + "rules": { + "typescript/no-implied-eval": "error" + } +} +``` + +::: + +## References + +- Rule Source diff --git a/src/docs/guide/usage/linter/rules/typescript/no-meaningless-void-operator.md b/src/docs/guide/usage/linter/rules/typescript/no-meaningless-void-operator.md new file mode 100644 index 0000000000..4937be305a --- /dev/null +++ b/src/docs/guide/usage/linter/rules/typescript/no-meaningless-void-operator.md @@ -0,0 +1,85 @@ + + + + +# typescript/no-meaningless-void-operator + +
+ + This rule is turned on by default. + + +🚧 An auto-fix is still under development. + +
+ +### What it does + +This rule disallows the void operator when its argument is already of type void or undefined. + +### Why is this bad? + +The void operator is useful when you want to execute an expression and force it to evaluate to undefined. However, using void on expressions that are already of type void or undefined is meaningless and adds unnecessary complexity to the code. + +### Examples + +Examples of **incorrect** code for this rule: + +```ts +function foo(): void { + return; +} + +void foo(); // meaningless, foo() already returns void + +void undefined; // meaningless, undefined is already undefined + +async function bar() { + void (await somePromise); // meaningless if somePromise resolves to void +} +``` + +Examples of **correct** code for this rule: + +```ts +function getValue(): number { + return 42; +} + +void getValue(); // meaningful, converts number to void + +void console.log("hello"); // meaningful, console.log returns undefined but we want to be explicit + +function processData() { + // some processing +} + +processData(); // no void needed since we don't care about return value +``` + +## How to use + +To **enable** this rule in the CLI or using the config file, you can use: + +::: code-group + +```bash [CLI] +oxlint --deny typescript/no-meaningless-void-operator +``` + +```json [Config (.oxlintrc.json)] +{ + "rules": { + "typescript/no-meaningless-void-operator": "error" + } +} +``` + +::: + +## References + +- Rule Source diff --git a/src/docs/guide/usage/linter/rules/typescript/no-misused-promises.md b/src/docs/guide/usage/linter/rules/typescript/no-misused-promises.md index f3f87cf4b5..3499dbbcb9 100644 --- a/src/docs/guide/usage/linter/rules/typescript/no-misused-promises.md +++ b/src/docs/guide/usage/linter/rules/typescript/no-misused-promises.md @@ -5,7 +5,7 @@ import { data } from '../version.data.js'; const source = `https://github.com/oxc-project/oxc/blob/${ data }/crates/oxc_linter/src/rules/typescript/no_misused_promises.rs`; -# typescript/no-misused-promises +# typescript/no-misused-promises
diff --git a/src/docs/guide/usage/linter/rules/typescript/no-misused-spread.md b/src/docs/guide/usage/linter/rules/typescript/no-misused-spread.md new file mode 100644 index 0000000000..0e37eb1dc3 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/typescript/no-misused-spread.md @@ -0,0 +1,87 @@ + + + + +# typescript/no-misused-spread + +
+ + This rule is turned on by default. + + +🚧 An auto-fix is still under development. + +
+ +### What it does + +This rule disallows spreading syntax in places where it doesn't make sense or could cause runtime errors. + +### Why is this bad? + +The spread operator can be misused in ways that might not be immediately obvious but can cause runtime errors or unexpected behavior. This rule helps catch common misuses. + +### Examples + +Examples of **incorrect** code for this rule: + +```ts +// Spreading a non-iterable value in an array +const num = 42; +const arr = [...num]; // Runtime error: num is not iterable + +// Spreading a Promise in an array +const promise = Promise.resolve([1, 2, 3]); +const arr2 = [...promise]; // Runtime error: Promise is not iterable + +// Spreading non-object in object literal +const str = "hello"; +const obj = { ...str }; // Creates { '0': 'h', '1': 'e', ... } which might be unexpected +``` + +Examples of **correct** code for this rule: + +```ts +// Spreading arrays +const arr1 = [1, 2, 3]; +const arr2 = [...arr1]; + +// Spreading objects +const obj1 = { a: 1, b: 2 }; +const obj2 = { ...obj1 }; + +// Spreading resolved Promise +const promise = Promise.resolve([1, 2, 3]); +const arr3 = [...(await promise)]; + +// Using Array.from for non-iterables if needed +const str = "hello"; +const arr4 = Array.from(str); // ['h', 'e', 'l', 'l', 'o'] +``` + +## How to use + +To **enable** this rule in the CLI or using the config file, you can use: + +::: code-group + +```bash [CLI] +oxlint --deny typescript/no-misused-spread +``` + +```json [Config (.oxlintrc.json)] +{ + "rules": { + "typescript/no-misused-spread": "error" + } +} +``` + +::: + +## References + +- Rule Source diff --git a/src/docs/guide/usage/linter/rules/typescript/no-mixed-enums.md b/src/docs/guide/usage/linter/rules/typescript/no-mixed-enums.md new file mode 100644 index 0000000000..5314881151 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/typescript/no-mixed-enums.md @@ -0,0 +1,89 @@ + + + + +# typescript/no-mixed-enums + +
+ +🚧 An auto-fix is still under development. + +
+ +### What it does + +This rule disallows enums from having both string and numeric members. + +### Why is this bad? + +TypeScript enums can have string, numeric, or computed members. Having mixed string and numeric members in the same enum can lead to confusion and unexpected runtime behavior due to how TypeScript compiles enums. + +### Examples + +Examples of **incorrect** code for this rule: + +```ts +enum Status { + Open = 1, + Closed = "closed", +} + +enum Direction { + Up = "up", + Down = 2, + Left = "left", + Right = 4, +} +``` + +Examples of **correct** code for this rule: + +```ts +// All numeric +enum Status { + Open = 1, + Closed = 2, +} + +// All string +enum Direction { + Up = "up", + Down = "down", + Left = "left", + Right = "right", +} + +// Auto-incremented numeric +enum Color { + Red, + Green, + Blue, +} +``` + +## How to use + +To **enable** this rule in the CLI or using the config file, you can use: + +::: code-group + +```bash [CLI] +oxlint --deny typescript/no-mixed-enums +``` + +```json [Config (.oxlintrc.json)] +{ + "rules": { + "typescript/no-mixed-enums": "error" + } +} +``` + +::: + +## References + +- Rule Source diff --git a/src/docs/guide/usage/linter/rules/typescript/no-redundant-type-constituents.md b/src/docs/guide/usage/linter/rules/typescript/no-redundant-type-constituents.md new file mode 100644 index 0000000000..233392252f --- /dev/null +++ b/src/docs/guide/usage/linter/rules/typescript/no-redundant-type-constituents.md @@ -0,0 +1,86 @@ + + + + +# typescript/no-redundant-type-constituents + +
+ + This rule is turned on by default. + + +🚧 An auto-fix is still under development. + +
+ +### What it does + +This rule disallows type constituents of unions and intersections that are redundant. + +### Why is this bad? + +Some constituents of union and intersection types can be redundant due to TypeScript's type system rules. These redundant constituents don't add any value and can make types harder to read and understand. + +### Examples + +Examples of **incorrect** code for this rule: + +```ts +// unknown is redundant in unions +type T1 = string | unknown; + +// any is redundant in unions +type T2 = string | any; + +// never is redundant in unions +type T3 = string | never; + +// Literal types that are wider than other types +type T4 = string | "hello"; + +// Object types that are subsets +type T5 = { a: string } | { a: string; b: number }; +``` + +Examples of **correct** code for this rule: + +```ts +type T1 = string | number; + +type T2 = "hello" | "world"; + +type T3 = { a: string } | { b: number }; + +// unknown in intersections is meaningful +type T4 = string & unknown; + +// never in intersections is meaningful +type T5 = string & never; +``` + +## How to use + +To **enable** this rule in the CLI or using the config file, you can use: + +::: code-group + +```bash [CLI] +oxlint --deny typescript/no-redundant-type-constituents +``` + +```json [Config (.oxlintrc.json)] +{ + "rules": { + "typescript/no-redundant-type-constituents": "error" + } +} +``` + +::: + +## References + +- Rule Source diff --git a/src/docs/guide/usage/linter/rules/typescript/no-unnecessary-boolean-literal-compare.md b/src/docs/guide/usage/linter/rules/typescript/no-unnecessary-boolean-literal-compare.md new file mode 100644 index 0000000000..26d5b8be3e --- /dev/null +++ b/src/docs/guide/usage/linter/rules/typescript/no-unnecessary-boolean-literal-compare.md @@ -0,0 +1,92 @@ + + + + +# typescript/no-unnecessary-boolean-literal-compare + +
+ +🚧 An auto-fix is still under development. + +
+ +### What it does + +This rule disallows unnecessary equality comparisons with boolean literals. + +### Why is this bad? + +Comparing boolean values to boolean literals is unnecessary when the comparison can be eliminated. These comparisons make code more verbose without adding value. + +### Examples + +Examples of **incorrect** code for this rule: + +```ts +declare const someCondition: boolean; + +if (someCondition === true) { + // ... +} + +if (someCondition === false) { + // ... +} + +if (someCondition !== true) { + // ... +} + +if (someCondition !== false) { + // ... +} + +const result = someCondition == true; +``` + +Examples of **correct** code for this rule: + +```ts +declare const someCondition: boolean; + +if (someCondition) { + // ... +} + +if (!someCondition) { + // ... +} + +// Comparisons with non-boolean types are allowed +declare const someValue: unknown; +if (someValue === true) { + // ... +} +``` + +## How to use + +To **enable** this rule in the CLI or using the config file, you can use: + +::: code-group + +```bash [CLI] +oxlint --deny typescript/no-unnecessary-boolean-literal-compare +``` + +```json [Config (.oxlintrc.json)] +{ + "rules": { + "typescript/no-unnecessary-boolean-literal-compare": "error" + } +} +``` + +::: + +## References + +- Rule Source diff --git a/src/docs/guide/usage/linter/rules/typescript/no-unnecessary-template-expression.md b/src/docs/guide/usage/linter/rules/typescript/no-unnecessary-template-expression.md new file mode 100644 index 0000000000..6c7b705c2c --- /dev/null +++ b/src/docs/guide/usage/linter/rules/typescript/no-unnecessary-template-expression.md @@ -0,0 +1,84 @@ + + + + +# typescript/no-unnecessary-template-expression + +
+ +🚧 An auto-fix is still under development. + +
+ +### What it does + +This rule disallows unnecessary template literals. + +### Why is this bad? + +Template literals should only be used when they are needed for string interpolation or multi-line strings. Using template literals when a simple string would suffice adds unnecessary complexity. + +### Examples + +Examples of **incorrect** code for this rule: + +```ts +const str1 = `Hello world`; + +const str2 = `42`; + +const str3 = `true`; + +// Template with only literal expressions +const str4 = `${"Hello"} ${"world"}`; +``` + +Examples of **correct** code for this rule: + +```ts +const str1 = "Hello world"; + +const str2 = "42"; + +const str3 = "true"; + +// Template with variable interpolation +const name = "world"; +const str4 = `Hello ${name}`; + +// Multi-line string +const multiline = ` + Hello + world +`; + +// Template with expression +const str5 = `Result: ${1 + 2}`; +``` + +## How to use + +To **enable** this rule in the CLI or using the config file, you can use: + +::: code-group + +```bash [CLI] +oxlint --deny typescript/no-unnecessary-template-expression +``` + +```json [Config (.oxlintrc.json)] +{ + "rules": { + "typescript/no-unnecessary-template-expression": "error" + } +} +``` + +::: + +## References + +- Rule Source diff --git a/src/docs/guide/usage/linter/rules/typescript/no-unnecessary-type-arguments.md b/src/docs/guide/usage/linter/rules/typescript/no-unnecessary-type-arguments.md new file mode 100644 index 0000000000..8bba3d8a08 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/typescript/no-unnecessary-type-arguments.md @@ -0,0 +1,97 @@ + + + + +# typescript/no-unnecessary-type-arguments + +
+ +🚧 An auto-fix is still under development. + +
+ +### What it does + +This rule disallows type arguments that are identical to the default type parameter. + +### Why is this bad? + +Explicit type arguments that are the same as their default values are unnecessary and add visual noise to the code. TypeScript will infer these types automatically. + +### Examples + +Examples of **incorrect** code for this rule: + +```ts +function identity(arg: T): T { + return arg; +} + +// Unnecessary type argument - string is the default +const result = identity("hello"); + +interface Container { + value: T; +} + +// Unnecessary type argument - number is the default +const container: Container = { value: 42 }; + +class MyClass { + constructor(public value: T) {} +} + +// Unnecessary type argument - boolean is the default +const instance = new MyClass(true); +``` + +Examples of **correct** code for this rule: + +```ts +function identity(arg: T): T { + return arg; +} + +// Using default type +const result1 = identity("hello"); + +// Using different type +const result2 = identity(42); + +interface Container { + value: T; +} + +// Using default type +const container1: Container = { value: 42 }; + +// Using different type +const container2: Container = { value: "hello" }; +``` + +## How to use + +To **enable** this rule in the CLI or using the config file, you can use: + +::: code-group + +```bash [CLI] +oxlint --deny typescript/no-unnecessary-type-arguments +``` + +```json [Config (.oxlintrc.json)] +{ + "rules": { + "typescript/no-unnecessary-type-arguments": "error" + } +} +``` + +::: + +## References + +- Rule Source diff --git a/src/docs/guide/usage/linter/rules/typescript/no-unnecessary-type-assertion.md b/src/docs/guide/usage/linter/rules/typescript/no-unnecessary-type-assertion.md new file mode 100644 index 0000000000..54190e7dad --- /dev/null +++ b/src/docs/guide/usage/linter/rules/typescript/no-unnecessary-type-assertion.md @@ -0,0 +1,82 @@ + + + + +# typescript/no-unnecessary-type-assertion + +
+ +🚧 An auto-fix is still under development. + +
+ +### What it does + +This rule disallows type assertions that do not change the type of an expression. + +### Why is this bad? + +Type assertions that don't actually change the type of an expression are unnecessary and can be safely removed. They add visual noise without providing any benefit and may indicate confusion about TypeScript's type system. + +### Examples + +Examples of **incorrect** code for this rule: + +```ts +const str: string = "hello"; +const redundant = str as string; // unnecessary, str is already string + +function getString(): string { + return "hello"; +} +const result = getString() as string; // unnecessary, getString() already returns string + +const num = 42; +const alsoRedundant = num as 42; // unnecessary if TypeScript can infer literal type + +// Unnecessary assertion to wider type +const literal = "hello" as string; +``` + +Examples of **correct** code for this rule: + +```ts +const unknown: unknown = "hello"; +const str = unknown as string; // necessary to narrow type + +const element = document.getElementById("myElement") as HTMLInputElement; // necessary for specific element type + +const obj = { name: "John" }; +const name = obj.name as const; // necessary for literal type + +// No assertion needed +const str2: string = "hello"; +const num: number = 42; +``` + +## How to use + +To **enable** this rule in the CLI or using the config file, you can use: + +::: code-group + +```bash [CLI] +oxlint --deny typescript/no-unnecessary-type-assertion +``` + +```json [Config (.oxlintrc.json)] +{ + "rules": { + "typescript/no-unnecessary-type-assertion": "error" + } +} +``` + +::: + +## References + +- Rule Source diff --git a/src/docs/guide/usage/linter/rules/typescript/no-unsafe-argument.md b/src/docs/guide/usage/linter/rules/typescript/no-unsafe-argument.md new file mode 100644 index 0000000000..227793c4e4 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/typescript/no-unsafe-argument.md @@ -0,0 +1,85 @@ + + + + +# typescript/no-unsafe-argument + +
+ +🚧 An auto-fix is still under development. + +
+ +### What it does + +This rule disallows calling a function with an argument which is typed as `any`. + +### Why is this bad? + +The `any` type in TypeScript is a dangerous "escape hatch" from the type system. Using `any` disables most type checking rules and is generally unsafe. When you pass a value typed as `any` to a function, you lose type safety for that function call. + +### Examples + +Examples of **incorrect** code for this rule: + +```ts +declare const anyValue: any; + +function takesString(str: string): void { + console.log(str.length); +} + +takesString(anyValue); // unsafe + +declare function takesNumber(num: number): number; +const result = takesNumber(anyValue); // unsafe +``` + +Examples of **correct** code for this rule: + +```ts +declare const stringValue: string; +declare const numberValue: number; +declare const unknownValue: unknown; + +function takesString(str: string): void { + console.log(str.length); +} + +takesString(stringValue); // safe + +// Type guard to safely use unknown +if (typeof unknownValue === "string") { + takesString(unknownValue); // safe after type guard +} + +// Type assertion if you're sure about the type +takesString(unknownValue as string); // explicitly unsafe, but intentional +``` + +## How to use + +To **enable** this rule in the CLI or using the config file, you can use: + +::: code-group + +```bash [CLI] +oxlint --deny typescript/no-unsafe-argument +``` + +```json [Config (.oxlintrc.json)] +{ + "rules": { + "typescript/no-unsafe-argument": "error" + } +} +``` + +::: + +## References + +- Rule Source diff --git a/src/docs/guide/usage/linter/rules/typescript/no-unsafe-assignment.md b/src/docs/guide/usage/linter/rules/typescript/no-unsafe-assignment.md new file mode 100644 index 0000000000..94a0757f8a --- /dev/null +++ b/src/docs/guide/usage/linter/rules/typescript/no-unsafe-assignment.md @@ -0,0 +1,91 @@ + + + + +# typescript/no-unsafe-assignment + +
+ +🚧 An auto-fix is still under development. + +
+ +### What it does + +This rule disallows assigning a value with type `any` to variables and properties. + +### Why is this bad? + +The `any` type in TypeScript disables type checking and can lead to runtime errors. When you assign an `any` value to a typed variable, you're essentially bypassing TypeScript's type safety without any guarantees about the actual value. + +### Examples + +Examples of **incorrect** code for this rule: + +```ts +declare const anyValue: any; + +const str: string = anyValue; // unsafe assignment + +let num: number; +num = anyValue; // unsafe assignment + +const obj = { + prop: anyValue as any, // unsafe assignment +}; + +interface User { + name: string; + age: number; +} + +const user: User = anyValue; // unsafe assignment +``` + +Examples of **correct** code for this rule: + +```ts +declare const stringValue: string; +declare const numberValue: number; +declare const unknownValue: unknown; + +const str: string = stringValue; // safe + +let num: number; +num = numberValue; // safe + +// Use type guards with unknown +if (typeof unknownValue === "string") { + const str2: string = unknownValue; // safe after type guard +} + +// Explicit any assignment (still not recommended, but intentional) +const anything: any = unknownValue; +``` + +## How to use + +To **enable** this rule in the CLI or using the config file, you can use: + +::: code-group + +```bash [CLI] +oxlint --deny typescript/no-unsafe-assignment +``` + +```json [Config (.oxlintrc.json)] +{ + "rules": { + "typescript/no-unsafe-assignment": "error" + } +} +``` + +::: + +## References + +- Rule Source diff --git a/src/docs/guide/usage/linter/rules/typescript/no-unsafe-call.md b/src/docs/guide/usage/linter/rules/typescript/no-unsafe-call.md new file mode 100644 index 0000000000..a54a82cd77 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/typescript/no-unsafe-call.md @@ -0,0 +1,83 @@ + + + + +# typescript/no-unsafe-call + +
+ +🚧 An auto-fix is still under development. + +
+ +### What it does + +This rule disallows calling a value with type `any`. + +### Why is this bad? + +The `any` type in TypeScript disables type checking. When you call a value typed as `any`, TypeScript cannot verify that it's actually a function, what parameters it expects, or what it returns. This can lead to runtime errors. + +### Examples + +Examples of **incorrect** code for this rule: + +```ts +declare const anyValue: any; + +anyValue(); // unsafe call + +anyValue(1, 2, 3); // unsafe call + +const result = anyValue("hello"); // unsafe call + +// Chained unsafe calls +anyValue().then().catch(); // unsafe +``` + +Examples of **correct** code for this rule: + +```ts +declare const fn: () => void; +declare const fnWithParams: (a: number, b: string) => boolean; +declare const unknownValue: unknown; + +fn(); // safe + +const result = fnWithParams(1, "hello"); // safe + +// Type guard for unknown +if (typeof unknownValue === "function") { + unknownValue(); // safe after type guard +} + +// Explicit type assertion if you're certain +(anyValue as () => void)(); // explicitly unsafe but intentional +``` + +## How to use + +To **enable** this rule in the CLI or using the config file, you can use: + +::: code-group + +```bash [CLI] +oxlint --deny typescript/no-unsafe-call +``` + +```json [Config (.oxlintrc.json)] +{ + "rules": { + "typescript/no-unsafe-call": "error" + } +} +``` + +::: + +## References + +- Rule Source diff --git a/src/docs/guide/usage/linter/rules/typescript/no-unsafe-enum-comparison.md b/src/docs/guide/usage/linter/rules/typescript/no-unsafe-enum-comparison.md new file mode 100644 index 0000000000..5cd0f5b69a --- /dev/null +++ b/src/docs/guide/usage/linter/rules/typescript/no-unsafe-enum-comparison.md @@ -0,0 +1,95 @@ + + + + +# typescript/no-unsafe-enum-comparison + +
+ +🚧 An auto-fix is still under development. + +
+ +### What it does + +This rule disallows comparing an enum value with a non-enum value. + +### Why is this bad? + +Enum values should only be compared with other values of the same enum type or their underlying literal values in a type-safe manner. Comparing enums with unrelated values can lead to unexpected behavior and defeats the purpose of using enums for type safety. + +### Examples + +Examples of **incorrect** code for this rule: + +```ts +enum Status { + Open = "open", + Closed = "closed", +} + +enum Color { + Red = "red", + Blue = "blue", +} + +declare const status: Status; +declare const color: Color; +declare const str: string; + +// Comparing enum with different enum +if (status === color) {} // unsafe + +// Comparing enum with string (unless it's a literal that matches) +if (status === str) {} // unsafe + +// Comparing with arbitrary value +if (status === "unknown") {} // unsafe +``` + +Examples of **correct** code for this rule: + +```ts +enum Status { + Open = "open", + Closed = "closed", +} + +declare const status: Status; + +// Comparing with same enum values +if (status === Status.Open) {} // safe + +// Comparing with the correct literal type +if (status === "open") {} // safe + +// Using enum methods +if (Object.values(Status).includes(someValue)) {} // safe way to check +``` + +## How to use + +To **enable** this rule in the CLI or using the config file, you can use: + +::: code-group + +```bash [CLI] +oxlint --deny typescript/no-unsafe-enum-comparison +``` + +```json [Config (.oxlintrc.json)] +{ + "rules": { + "typescript/no-unsafe-enum-comparison": "error" + } +} +``` + +::: + +## References + +- Rule Source diff --git a/src/docs/guide/usage/linter/rules/typescript/no-unsafe-member-access.md b/src/docs/guide/usage/linter/rules/typescript/no-unsafe-member-access.md new file mode 100644 index 0000000000..d195aa909d --- /dev/null +++ b/src/docs/guide/usage/linter/rules/typescript/no-unsafe-member-access.md @@ -0,0 +1,83 @@ + + + + +# typescript/no-unsafe-member-access + +
+ +🚧 An auto-fix is still under development. + +
+ +### What it does + +This rule disallows member access on a value with type `any`. + +### Why is this bad? + +The `any` type in TypeScript disables type checking. When you access a member (property or method) on a value typed as `any`, TypeScript cannot verify that the member exists or what type it has. This can lead to runtime errors. + +### Examples + +Examples of **incorrect** code for this rule: + +```ts +declare const anyValue: any; + +anyValue.foo; // unsafe member access + +anyValue.bar.baz; // unsafe nested member access + +anyValue["key"]; // unsafe computed member access + +const result = anyValue.method(); // unsafe method access +``` + +Examples of **correct** code for this rule: + +```ts +declare const obj: { foo: string; bar: { baz: number } }; +declare const unknownValue: unknown; + +obj.foo; // safe + +obj.bar.baz; // safe + +obj["foo"]; // safe + +// Type guard for unknown +if (typeof unknownValue === "object" && unknownValue !== null && "foo" in unknownValue) { + console.log(unknownValue.foo); // safe after type guard +} + +// Explicit type assertion if needed +(anyValue as { foo: string }).foo; // explicitly unsafe but intentional +``` + +## How to use + +To **enable** this rule in the CLI or using the config file, you can use: + +::: code-group + +```bash [CLI] +oxlint --deny typescript/no-unsafe-member-access +``` + +```json [Config (.oxlintrc.json)] +{ + "rules": { + "typescript/no-unsafe-member-access": "error" + } +} +``` + +::: + +## References + +- Rule Source diff --git a/src/docs/guide/usage/linter/rules/typescript/no-unsafe-return.md b/src/docs/guide/usage/linter/rules/typescript/no-unsafe-return.md new file mode 100644 index 0000000000..f9c19aee35 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/typescript/no-unsafe-return.md @@ -0,0 +1,90 @@ + + + + +# typescript/no-unsafe-return + +
+ +🚧 An auto-fix is still under development. + +
+ +### What it does + +This rule disallows returning a value with type `any` from a function. + +### Why is this bad? + +The `any` type in TypeScript disables type checking. When you return a value typed as `any` from a function, you're essentially passing the type-safety problem to the caller without providing any guarantees about what the function actually returns. + +### Examples + +Examples of **incorrect** code for this rule: + +```ts +declare const anyValue: any; + +function getString(): string { + return anyValue; // unsafe return +} + +const getNumber = (): number => anyValue; // unsafe return + +function processData(): { name: string; age: number } { + return anyValue; // unsafe return +} +``` + +Examples of **correct** code for this rule: + +```ts +declare const stringValue: string; +declare const numberValue: number; +declare const unknownValue: unknown; + +function getString(): string { + return stringValue; // safe +} + +const getNumber = (): number => numberValue; // safe + +function processUnknown(): unknown { + return unknownValue; // safe - explicitly returning unknown +} + +// Type guard to safely return +function safeGetString(): string | null { + if (typeof unknownValue === "string") { + return unknownValue; // safe after type guard + } + return null; +} +``` + +## How to use + +To **enable** this rule in the CLI or using the config file, you can use: + +::: code-group + +```bash [CLI] +oxlint --deny typescript/no-unsafe-return +``` + +```json [Config (.oxlintrc.json)] +{ + "rules": { + "typescript/no-unsafe-return": "error" + } +} +``` + +::: + +## References + +- Rule Source diff --git a/src/docs/guide/usage/linter/rules/typescript/no-unsafe-type-assertion.md b/src/docs/guide/usage/linter/rules/typescript/no-unsafe-type-assertion.md new file mode 100644 index 0000000000..ccd2ba4739 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/typescript/no-unsafe-type-assertion.md @@ -0,0 +1,88 @@ + + + + +# typescript/no-unsafe-type-assertion + +
+ +🚧 An auto-fix is still under development. + +
+ +### What it does + +This rule disallows type assertions using the `any` type. + +### Why is this bad? + +Type assertions using `any` completely bypass TypeScript's type system and can lead to runtime errors. They should be avoided in favor of more specific type assertions or proper type guards. + +### Examples + +Examples of **incorrect** code for this rule: + +```ts +declare const value: unknown; + +const str = value as any; // unsafe type assertion + +const obj = value as any as string; // double assertion through any + +function processValue(input: unknown) { + const processed = input as any; // unsafe + return processed.someProperty; +} +``` + +Examples of **correct** code for this rule: + +```ts +declare const value: unknown; + +// Use specific type assertions +const str = value as string; // more specific assertion + +// Use type guards +if (typeof value === "string") { + const str2 = value; // safe, no assertion needed +} + +// Use proper interface assertions +interface User { + name: string; + age: number; +} + +const user = value as User; // specific type assertion + +// Use unknown for truly unknown values +const unknown: unknown = value; +``` + +## How to use + +To **enable** this rule in the CLI or using the config file, you can use: + +::: code-group + +```bash [CLI] +oxlint --deny typescript/no-unsafe-type-assertion +``` + +```json [Config (.oxlintrc.json)] +{ + "rules": { + "typescript/no-unsafe-type-assertion": "error" + } +} +``` + +::: + +## References + +- Rule Source diff --git a/src/docs/guide/usage/linter/rules/typescript/no-unsafe-unary-minus.md b/src/docs/guide/usage/linter/rules/typescript/no-unsafe-unary-minus.md new file mode 100644 index 0000000000..87099a27de --- /dev/null +++ b/src/docs/guide/usage/linter/rules/typescript/no-unsafe-unary-minus.md @@ -0,0 +1,91 @@ + + + + +# typescript/no-unsafe-unary-minus + +
+ + This rule is turned on by default. + + +🚧 An auto-fix is still under development. + +
+ +### What it does + +This rule disallows using the unary minus operator on a value which is not of type 'number' | 'bigint'. + +### Why is this bad? + +The unary minus operator should only be used on numeric values. Using it on other types can lead to unexpected behavior due to JavaScript's type coercion rules. + +### Examples + +Examples of **incorrect** code for this rule: + +```ts +declare const value: any; +const result1 = -value; // unsafe on any + +declare const str: string; +const result2 = -str; // unsafe on string + +declare const bool: boolean; +const result3 = -bool; // unsafe on boolean + +declare const obj: object; +const result4 = -obj; // unsafe on object + +declare const arr: any[]; +const result5 = -arr; // unsafe on array +``` + +Examples of **correct** code for this rule: + +```ts +declare const num: number; +const result1 = -num; // safe + +declare const bigint: bigint; +const result2 = -bigint; // safe + +const literal = -42; // safe + +const bigintLiteral = -42n; // safe + +declare const union: number | bigint; +const result3 = -union; // safe + +// Convert to number first if needed +declare const str: string; +const result4 = -Number(str); // safe conversion +``` + +## How to use + +To **enable** this rule in the CLI or using the config file, you can use: + +::: code-group + +```bash [CLI] +oxlint --deny typescript/no-unsafe-unary-minus +``` + +```json [Config (.oxlintrc.json)] +{ + "rules": { + "typescript/no-unsafe-unary-minus": "error" + } +} +``` + +::: + +## References + +- Rule Source diff --git a/src/docs/guide/usage/linter/rules/typescript/non-nullable-type-assertion-style.md b/src/docs/guide/usage/linter/rules/typescript/non-nullable-type-assertion-style.md new file mode 100644 index 0000000000..83744b9ecc --- /dev/null +++ b/src/docs/guide/usage/linter/rules/typescript/non-nullable-type-assertion-style.md @@ -0,0 +1,90 @@ + + + + +# typescript/non-nullable-type-assertion-style + +
+ +🚧 An auto-fix is still under development. + +
+ +### What it does + +This rule prefers a non-null assertion over an explicit type cast for non-nullable types. + +### Why is this bad? + +When you know that a value cannot be null or undefined, you can use either a non-null assertion (`!`) or a type assertion (`as Type`). The non-null assertion is more concise and clearly communicates the intent that you're asserting the value is not null/undefined. + +### Examples + +Examples of **incorrect** code for this rule: + +```ts +declare const value: string | null; + +// Type assertion when non-null assertion would be clearer +const result1 = value as string; + +declare const maybe: number | undefined; +const result2 = maybe as number; + +// In function calls +function takesString(s: string) { + console.log(s); +} + +takesString(value as string); +``` + +Examples of **correct** code for this rule: + +```ts +declare const value: string | null; + +// Non-null assertion for non-nullable types +const result1 = value!; + +declare const maybe: number | undefined; +const result2 = maybe!; + +// In function calls +function takesString(s: string) { + console.log(s); +} + +takesString(value!); + +// Type assertion for actual type changes is still fine +declare const unknown: unknown; +const str = unknown as string; // This is a different type, not just removing null +``` + +## How to use + +To **enable** this rule in the CLI or using the config file, you can use: + +::: code-group + +```bash [CLI] +oxlint --deny typescript/non-nullable-type-assertion-style +``` + +```json [Config (.oxlintrc.json)] +{ + "rules": { + "typescript/non-nullable-type-assertion-style": "error" + } +} +``` + +::: + +## References + +- Rule Source diff --git a/src/docs/guide/usage/linter/rules/typescript/only-throw-error.md b/src/docs/guide/usage/linter/rules/typescript/only-throw-error.md new file mode 100644 index 0000000000..0f0b62921d --- /dev/null +++ b/src/docs/guide/usage/linter/rules/typescript/only-throw-error.md @@ -0,0 +1,90 @@ + + + + +# typescript/only-throw-error + +
+ +🚧 An auto-fix is still under development. + +
+ +### What it does + +This rule disallows throwing non-Error values. + +### Why is this bad? + +It's considered good practice to only throw Error objects (or subclasses of Error). This is because Error objects automatically capture a stack trace, which is useful for debugging. Additionally, some tools and environments expect thrown values to be Error objects. + +### Examples + +Examples of **incorrect** code for this rule: + +```ts +throw "error"; // throwing string + +throw 42; // throwing number + +throw true; // throwing boolean + +throw { message: "error" }; // throwing plain object + +throw null; // throwing null + +throw undefined; // throwing undefined + +const error = "Something went wrong"; +throw error; // throwing non-Error variable +``` + +Examples of **correct** code for this rule: + +```ts +throw new Error("Something went wrong"); + +throw new TypeError("Invalid type"); + +throw new RangeError("Value out of range"); + +// Custom Error subclasses +class CustomError extends Error { + constructor(message: string) { + super(message); + this.name = "CustomError"; + } +} +throw new CustomError("Custom error occurred"); + +// Variables that are Error objects +const error = new Error("Error message"); +throw error; +``` + +## How to use + +To **enable** this rule in the CLI or using the config file, you can use: + +::: code-group + +```bash [CLI] +oxlint --deny typescript/only-throw-error +``` + +```json [Config (.oxlintrc.json)] +{ + "rules": { + "typescript/only-throw-error": "error" + } +} +``` + +::: + +## References + +- Rule Source diff --git a/src/docs/guide/usage/linter/rules/typescript/prefer-promise-reject-errors.md b/src/docs/guide/usage/linter/rules/typescript/prefer-promise-reject-errors.md new file mode 100644 index 0000000000..05eacfebcf --- /dev/null +++ b/src/docs/guide/usage/linter/rules/typescript/prefer-promise-reject-errors.md @@ -0,0 +1,90 @@ + + + + +# typescript/prefer-promise-reject-errors + +
+ +🚧 An auto-fix is still under development. + +
+ +### What it does + +This rule enforces passing an Error object to Promise.reject(). + +### Why is this bad? + +It's considered good practice to only reject promises with Error objects. This is because Error objects automatically capture a stack trace, which is useful for debugging. Additionally, some tools and environments expect rejection reasons to be Error objects. + +### Examples + +Examples of **incorrect** code for this rule: + +```ts +Promise.reject("error"); // rejecting with string + +Promise.reject(42); // rejecting with number + +Promise.reject(true); // rejecting with boolean + +Promise.reject({ message: "error" }); // rejecting with plain object + +Promise.reject(null); // rejecting with null + +Promise.reject(); // rejecting with undefined + +const error = "Something went wrong"; +Promise.reject(error); // rejecting with non-Error variable +``` + +Examples of **correct** code for this rule: + +```ts +Promise.reject(new Error("Something went wrong")); + +Promise.reject(new TypeError("Invalid type")); + +Promise.reject(new RangeError("Value out of range")); + +// Custom Error subclasses +class CustomError extends Error { + constructor(message: string) { + super(message); + this.name = "CustomError"; + } +} +Promise.reject(new CustomError("Custom error occurred")); + +// Variables that are Error objects +const error = new Error("Error message"); +Promise.reject(error); +``` + +## How to use + +To **enable** this rule in the CLI or using the config file, you can use: + +::: code-group + +```bash [CLI] +oxlint --deny typescript/prefer-promise-reject-errors +``` + +```json [Config (.oxlintrc.json)] +{ + "rules": { + "typescript/prefer-promise-reject-errors": "error" + } +} +``` + +::: + +## References + +- Rule Source diff --git a/src/docs/guide/usage/linter/rules/typescript/prefer-reduce-type-parameter.md b/src/docs/guide/usage/linter/rules/typescript/prefer-reduce-type-parameter.md new file mode 100644 index 0000000000..0ce757196e --- /dev/null +++ b/src/docs/guide/usage/linter/rules/typescript/prefer-reduce-type-parameter.md @@ -0,0 +1,91 @@ + + + + +# typescript/prefer-reduce-type-parameter + +
+ +🚧 An auto-fix is still under development. + +
+ +### What it does + +This rule prefers using a type parameter for the accumulator in Array.reduce instead of casting. + +### Why is this bad? + +Array.reduce can be called with a generic type parameter to specify the type of the accumulator. This is preferred over casting the result because it provides better type safety and is more explicit about the intended type. + +### Examples + +Examples of **incorrect** code for this rule: + +```ts +const numbers = [1, 2, 3]; + +// Casting the result +const sum = numbers.reduce((acc, val) => acc + val, 0) as number; + +// Using type assertion on accumulator +const result = [1, 2, 3].reduce((acc: string[], curr) => { + acc.push(curr.toString()); + return acc; +}, [] as string[]); +``` + +Examples of **correct** code for this rule: + +```ts +const numbers = [1, 2, 3]; + +// Using type parameter +const sum = numbers.reduce((acc, val) => acc + val, 0); + +// Type parameter for complex types +const result = [1, 2, 3].reduce((acc, curr) => { + acc.push(curr.toString()); + return acc; +}, []); + +// When TypeScript can infer the type, no parameter needed +const simpleSum = numbers.reduce((acc, val) => acc + val, 0); + +// Object accumulator with type parameter +interface Count { + [key: string]: number; +} + +const counts = ["a", "b", "a"].reduce((acc, item) => { + acc[item] = (acc[item] || 0) + 1; + return acc; +}, {}); +``` + +## How to use + +To **enable** this rule in the CLI or using the config file, you can use: + +::: code-group + +```bash [CLI] +oxlint --deny typescript/prefer-reduce-type-parameter +``` + +```json [Config (.oxlintrc.json)] +{ + "rules": { + "typescript/prefer-reduce-type-parameter": "error" + } +} +``` + +::: + +## References + +- Rule Source diff --git a/src/docs/guide/usage/linter/rules/typescript/prefer-return-this-type.md b/src/docs/guide/usage/linter/rules/typescript/prefer-return-this-type.md new file mode 100644 index 0000000000..1a06f39d18 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/typescript/prefer-return-this-type.md @@ -0,0 +1,110 @@ + + + + +# typescript/prefer-return-this-type + +
+ +🚧 An auto-fix is still under development. + +
+ +### What it does + +This rule enforces using `this` types for return types when possible. + +### Why is this bad? + +Classes that have methods which return the instance itself should use `this` as the return type instead of the class name. This provides better type safety for inheritance, as the return type will be the actual subclass type rather than the base class type. + +### Examples + +Examples of **incorrect** code for this rule: + +```ts +class Builder { + private value: string = ""; + + setValue(value: string): Builder { // Should return 'this' + this.value = value; + return this; + } + + build(): string { + return this.value; + } +} + +class FluentAPI { + method1(): FluentAPI { // Should return 'this' + return this; + } + + method2(): FluentAPI { // Should return 'this' + return this; + } +} +``` + +Examples of **correct** code for this rule: + +```ts +class Builder { + private value: string = ""; + + setValue(value: string): this { + this.value = value; + return this; + } + + build(): string { + return this.value; + } +} + +class FluentAPI { + method1(): this { + return this; + } + + method2(): this { + return this; + } +} + +// Now inheritance works correctly +class ExtendedBuilder extends Builder { + setPrefix(prefix: string): this { + // The return type is 'this' (ExtendedBuilder), not Builder + return this.setValue(prefix + this.getValue()); + } +} +``` + +## How to use + +To **enable** this rule in the CLI or using the config file, you can use: + +::: code-group + +```bash [CLI] +oxlint --deny typescript/prefer-return-this-type +``` + +```json [Config (.oxlintrc.json)] +{ + "rules": { + "typescript/prefer-return-this-type": "error" + } +} +``` + +::: + +## References + +- Rule Source diff --git a/src/docs/guide/usage/linter/rules/typescript/promise-function-async.md b/src/docs/guide/usage/linter/rules/typescript/promise-function-async.md new file mode 100644 index 0000000000..57159dc62e --- /dev/null +++ b/src/docs/guide/usage/linter/rules/typescript/promise-function-async.md @@ -0,0 +1,102 @@ + + + + +# typescript/promise-function-async + +
+ +🚧 An auto-fix is still under development. + +
+ +### What it does + +This rule requires any function or method that returns a Promise to be marked as async. + +### Why is this bad? + +Functions that return Promises should typically be marked as `async` to make their asynchronous nature clear and to enable the use of `await` within them. This makes the code more readable and helps prevent common mistakes with Promise handling. + +### Examples + +Examples of **incorrect** code for this rule: + +```ts +// Function returning Promise without async +function fetchData(): Promise { + return fetch("/api/data").then(res => res.text()); +} + +// Method returning Promise without async +class DataService { + getData(): Promise { + return fetch("/api/data").then(res => res.json()); + } +} + +// Arrow function returning Promise without async +const processData = (): Promise => { + return Promise.resolve(); +}; +``` + +Examples of **correct** code for this rule: + +```ts +// Async function +async function fetchData(): Promise { + const response = await fetch("/api/data"); + return response.text(); +} + +// Async method +class DataService { + async getData(): Promise { + const response = await fetch("/api/data"); + return response.json(); + } +} + +// Async arrow function +const processData = async (): Promise => { + await someAsyncOperation(); +}; + +// Functions that don't return Promise are fine +function syncFunction(): string { + return "hello"; +} + +// Functions returning Promise-like but not actual Promise +function createThenable(): { then: Function } { + return { then: () => {} }; +} +``` + +## How to use + +To **enable** this rule in the CLI or using the config file, you can use: + +::: code-group + +```bash [CLI] +oxlint --deny typescript/promise-function-async +``` + +```json [Config (.oxlintrc.json)] +{ + "rules": { + "typescript/promise-function-async": "error" + } +} +``` + +::: + +## References + +- Rule Source diff --git a/src/docs/guide/usage/linter/rules/typescript/related-getter-setter-pairs.md b/src/docs/guide/usage/linter/rules/typescript/related-getter-setter-pairs.md new file mode 100644 index 0000000000..7831a141fd --- /dev/null +++ b/src/docs/guide/usage/linter/rules/typescript/related-getter-setter-pairs.md @@ -0,0 +1,104 @@ + + + + +# typescript/related-getter-setter-pairs + +
+ +🚧 An auto-fix is still under development. + +
+ +### What it does + +This rule enforces that getters and setters for the same property are defined together and have related types. + +### Why is this bad? + +When you define a getter and setter for the same property, they should typically be defined together and work with compatible types. Having mismatched types or defining them separately can lead to confusion and potential runtime errors. + +### Examples + +Examples of **incorrect** code for this rule: + +```ts +class Example { + // Getter and setter with incompatible types + get value(): string { + return this._value.toString(); + } + + set value(val: number) { // Incompatible with getter + this._value = val; + } + + private _value: number = 0; +} + +// Getter without corresponding setter or vice versa might be flagged +class IncompleteProperty { + get readOnlyValue(): string { + return "constant"; + } + // Missing setter - might be intended, but should be consistent +} +``` + +Examples of **correct** code for this rule: + +```ts +class Example { + // Getter and setter with compatible types + get value(): string { + return this._value; + } + + set value(val: string) { + this._value = val; + } + + private _value: string = ""; +} + +// Read-only property with only getter +class ReadOnlyProperty { + get constant(): string { + return "constant value"; + } +} + +// Write-only property with only setter (less common but valid) +class WriteOnlyProperty { + set logger(message: string) { + console.log(message); + } +} +``` + +## How to use + +To **enable** this rule in the CLI or using the config file, you can use: + +::: code-group + +```bash [CLI] +oxlint --deny typescript/related-getter-setter-pairs +``` + +```json [Config (.oxlintrc.json)] +{ + "rules": { + "typescript/related-getter-setter-pairs": "error" + } +} +``` + +::: + +## References + +- Rule Source diff --git a/src/docs/guide/usage/linter/rules/typescript/require-array-sort-compare.md b/src/docs/guide/usage/linter/rules/typescript/require-array-sort-compare.md new file mode 100644 index 0000000000..98b1db0cba --- /dev/null +++ b/src/docs/guide/usage/linter/rules/typescript/require-array-sort-compare.md @@ -0,0 +1,93 @@ + + + + +# typescript/require-array-sort-compare + +
+ + This rule is turned on by default. + + +🚧 An auto-fix is still under development. + +
+ +### What it does + +This rule requires Array.sort() to be called with a comparison function. + +### Why is this bad? + +When Array.sort() is called without a comparison function, it converts elements to strings and sorts them lexicographically. This often leads to unexpected results, especially with numbers where `[1, 10, 2].sort()` returns `[1, 10, 2]` instead of `[1, 2, 10]`. + +### Examples + +Examples of **incorrect** code for this rule: + +```ts +const numbers = [3, 1, 4, 1, 5]; +numbers.sort(); // Lexicographic sort, not numeric + +const mixedArray = ["10", "2", "1"]; +mixedArray.sort(); // Might be intended, but explicit compareFn is clearer + +[3, 1, 4].sort(); // Will sort as strings: ['1', '3', '4'] +``` + +Examples of **correct** code for this rule: + +```ts +const numbers = [3, 1, 4, 1, 5]; + +// Numeric sort +numbers.sort((a, b) => a - b); + +// Reverse numeric sort +numbers.sort((a, b) => b - a); + +// String sort (explicit) +const strings = ["banana", "apple", "cherry"]; +strings.sort((a, b) => a.localeCompare(b)); + +// Custom object sorting +interface Person { + name: string; + age: number; +} + +const people: Person[] = [ + { name: "Alice", age: 30 }, + { name: "Bob", age: 25 }, +]; + +people.sort((a, b) => a.age - b.age); +people.sort((a, b) => a.name.localeCompare(b.name)); +``` + +## How to use + +To **enable** this rule in the CLI or using the config file, you can use: + +::: code-group + +```bash [CLI] +oxlint --deny typescript/require-array-sort-compare +``` + +```json [Config (.oxlintrc.json)] +{ + "rules": { + "typescript/require-array-sort-compare": "error" + } +} +``` + +::: + +## References + +- Rule Source diff --git a/src/docs/guide/usage/linter/rules/typescript/require-await.md b/src/docs/guide/usage/linter/rules/typescript/require-await.md new file mode 100644 index 0000000000..8f814cd60a --- /dev/null +++ b/src/docs/guide/usage/linter/rules/typescript/require-await.md @@ -0,0 +1,106 @@ + + + + +# typescript/require-await + +
+ +🚧 An auto-fix is still under development. + +
+ +### What it does + +This rule disallows async functions which do not have an await expression. + +### Why is this bad? + +Async functions that don't use await are usually a mistake. They return a Promise unnecessarily and can often be converted to regular functions. This can improve performance and make the code clearer. + +### Examples + +Examples of **incorrect** code for this rule: + +```ts +// Async function without await +async function fetchData() { + return fetch("/api/data"); +} + +// Async arrow function without await +const processData = async () => { + return someData.map(x => x * 2); +}; + +// Async method without await +class DataService { + async getData() { + return this.data; + } +} + +// Async function that returns Promise but doesn't await +async function getPromise() { + return Promise.resolve("value"); +} +``` + +Examples of **correct** code for this rule: + +```ts +// Async function with await +async function fetchData() { + const response = await fetch("/api/data"); + return response.json(); +} + +// Regular function returning Promise +function fetchDataSync() { + return fetch("/api/data"); +} + +// Async function with await in conditional +async function conditionalAwait(condition: boolean) { + if (condition) { + return await someAsyncOperation(); + } + return "default"; +} + +// Async function with await in loop +async function processItems(items: string[]) { + const results = []; + for (const item of items) { + results.push(await processItem(item)); + } + return results; +} +``` + +## How to use + +To **enable** this rule in the CLI or using the config file, you can use: + +::: code-group + +```bash [CLI] +oxlint --deny typescript/require-await +``` + +```json [Config (.oxlintrc.json)] +{ + "rules": { + "typescript/require-await": "error" + } +} +``` + +::: + +## References + +- Rule Source diff --git a/src/docs/guide/usage/linter/rules/typescript/restrict-plus-operands.md b/src/docs/guide/usage/linter/rules/typescript/restrict-plus-operands.md new file mode 100644 index 0000000000..8160bfb19f --- /dev/null +++ b/src/docs/guide/usage/linter/rules/typescript/restrict-plus-operands.md @@ -0,0 +1,92 @@ + + + + +# typescript/restrict-plus-operands + +
+ +🚧 An auto-fix is still under development. + +
+ +### What it does + +This rule requires both operands of addition to be the same type and be number, string, or any. + +### Why is this bad? + +JavaScript's + operator can be used for both numeric addition and string concatenation. When the operands are of different types, JavaScript's type coercion rules can lead to unexpected results. This rule helps prevent these issues by requiring both operands to be of compatible types. + +### Examples + +Examples of **incorrect** code for this rule: + +```ts +declare const num: number; +declare const str: string; +declare const bool: boolean; +declare const obj: object; + +// Mixed types +const result1 = num + str; // number + string +const result2 = str + bool; // string + boolean +const result3 = num + bool; // number + boolean +const result4 = obj + str; // object + string + +// Literals with different types +const result5 = 42 + "hello"; // number literal + string literal +const result6 = true + 5; // boolean literal + number literal +``` + +Examples of **correct** code for this rule: + +```ts +declare const num1: number; +declare const num2: number; +declare const str1: string; +declare const str2: string; + +// Same types +const sum = num1 + num2; // number + number +const concat = str1 + str2; // string + string + +// Explicit conversions +const result1 = num1 + String(num2); // Convert to string first +const result2 = String(num1) + str1; // Convert to string first +const result3 = Number(str1) + num1; // Convert to number first + +// Template literals for string concatenation +const result4 = `${num1}${str1}`; // Clear intent to concatenate + +// Literals of same type +const numResult = 42 + 58; // number + number +const strResult = "hello" + "world"; // string + string +``` + +## How to use + +To **enable** this rule in the CLI or using the config file, you can use: + +::: code-group + +```bash [CLI] +oxlint --deny typescript/restrict-plus-operands +``` + +```json [Config (.oxlintrc.json)] +{ + "rules": { + "typescript/restrict-plus-operands": "error" + } +} +``` + +::: + +## References + +- Rule Source diff --git a/src/docs/guide/usage/linter/rules/typescript/restrict-template-expressions.md b/src/docs/guide/usage/linter/rules/typescript/restrict-template-expressions.md new file mode 100644 index 0000000000..c8784829be --- /dev/null +++ b/src/docs/guide/usage/linter/rules/typescript/restrict-template-expressions.md @@ -0,0 +1,103 @@ + + + + +# typescript/restrict-template-expressions + +
+ + This rule is turned on by default. + + +🚧 An auto-fix is still under development. + +
+ +### What it does + +This rule restricts the types allowed in template literal expressions. + +### Why is this bad? + +Template literals will call toString() on the interpolated values. Some types don't have meaningful string representations (like objects that become "[object Object]") or may not have a toString method at all. This rule helps ensure that only appropriate types are used in template expressions. + +### Examples + +Examples of **incorrect** code for this rule: + +```ts +declare const obj: object; +declare const sym: symbol; +declare const fn: () => void; +declare const arr: unknown[]; + +// Objects become "[object Object]" +const str1 = `Value: ${obj}`; + +// Symbols might not be what you expect +const str2 = `Symbol: ${sym}`; + +// Functions become their source code or "[Function]" +const str3 = `Function: ${fn}`; + +// Arrays might not format as expected +const str4 = `Array: ${arr}`; + +// undefined/null become "undefined"/"null" which might be confusing +declare const maybeValue: string | undefined; +const str5 = `Value: ${maybeValue}`; // Could be "Value: undefined" +``` + +Examples of **correct** code for this rule: + +```ts +declare const str: string; +declare const num: number; +declare const bool: boolean; +declare const obj: object; + +// Safe types +const result1 = `String: ${str}`; +const result2 = `Number: ${num}`; +const result3 = `Boolean: ${bool}`; + +// Explicit conversions for complex types +const result4 = `Object: ${JSON.stringify(obj)}`; +const result5 = `Array: ${arr.join(", ")}`; + +// Handle undefined/null explicitly +declare const maybeValue: string | undefined; +const result6 = `Value: ${maybeValue ?? "N/A"}`; +const result7 = `Value: ${maybeValue || "default"}`; + +// Type guards for unknown values +declare const unknown: unknown; +const result8 = typeof unknown === "string" ? `Value: ${unknown}` : "Invalid"; +``` + +## How to use + +To **enable** this rule in the CLI or using the config file, you can use: + +::: code-group + +```bash [CLI] +oxlint --deny typescript/restrict-template-expressions +``` + +```json [Config (.oxlintrc.json)] +{ + "rules": { + "typescript/restrict-template-expressions": "error" + } +} +``` + +::: + +## References + +- Rule Source diff --git a/src/docs/guide/usage/linter/rules/typescript/return-await.md b/src/docs/guide/usage/linter/rules/typescript/return-await.md new file mode 100644 index 0000000000..b18d1f051b --- /dev/null +++ b/src/docs/guide/usage/linter/rules/typescript/return-await.md @@ -0,0 +1,102 @@ + + + + +# typescript/return-await + +
+ +🚧 An auto-fix is still under development. + +
+ +### What it does + +This rule enforces consistent returning of awaited values from async functions. + +### Why is this bad? + +There are different patterns for returning awaited values from async functions. Sometimes you want to await before returning (to handle errors in the current function), and sometimes you want to return the Promise directly (for better performance). This rule helps enforce consistency. + +### Examples + +Examples of **incorrect** code for this rule (depending on configuration): + +```ts +// If configured to require await: +async function fetchData() { + return fetch("/api/data"); // Should be: return await fetch('/api/data'); +} + +async function processData() { + return someAsyncOperation(); // Should be: return await someAsyncOperation(); +} + +// If configured to disallow unnecessary await: +async function fetchData() { + return await fetch("/api/data"); // Should be: return fetch('/api/data'); +} + +async function processData() { + return await someAsyncOperation(); // Should be: return someAsyncOperation(); +} +``` + +Examples of **correct** code for this rule: + +```ts +// When await is required for error handling: +async function fetchData() { + try { + return await fetch("/api/data"); + } catch (error) { + console.error("Fetch failed:", error); + throw error; + } +} + +// When returning Promise directly for performance: +async function fetchData() { + return fetch("/api/data"); +} + +// Processing before return requires await: +async function fetchAndProcess() { + const response = await fetch("/api/data"); + return response.json(); +} + +// Multiple async operations: +async function multipleOperations() { + const data1 = await fetchData1(); + const data2 = await fetchData2(); + return data1 + data2; +} +``` + +## How to use + +To **enable** this rule in the CLI or using the config file, you can use: + +::: code-group + +```bash [CLI] +oxlint --deny typescript/return-await +``` + +```json [Config (.oxlintrc.json)] +{ + "rules": { + "typescript/return-await": "error" + } +} +``` + +::: + +## References + +- Rule Source diff --git a/src/docs/guide/usage/linter/rules/typescript/switch-exhaustiveness-check.md b/src/docs/guide/usage/linter/rules/typescript/switch-exhaustiveness-check.md new file mode 100644 index 0000000000..bbca03a321 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/typescript/switch-exhaustiveness-check.md @@ -0,0 +1,132 @@ + + + + +# typescript/switch-exhaustiveness-check + +
+ +🚧 An auto-fix is still under development. + +
+ +### What it does + +This rule requires switch statements to be exhaustive when switching on union types. + +### Why is this bad? + +When switching on a union type, it's important to handle all possible cases to avoid runtime errors. TypeScript can help ensure exhaustiveness, but only if the switch statement is properly structured with a default case that TypeScript can analyze. + +### Examples + +Examples of **incorrect** code for this rule: + +```ts +type Status = "pending" | "approved" | "rejected"; + +function handleStatus(status: Status) { + switch (status) { + case "pending": + return "Waiting for approval"; + case "approved": + return "Request approved"; + // Missing 'rejected' case + } +} + +enum Color { + Red, + Green, + Blue, +} + +function getColorName(color: Color) { + switch (color) { + case Color.Red: + return "red"; + case Color.Green: + return "green"; + // Missing Color.Blue case + } +} +``` + +Examples of **correct** code for this rule: + +```ts +type Status = "pending" | "approved" | "rejected"; + +function handleStatus(status: Status) { + switch (status) { + case "pending": + return "Waiting for approval"; + case "approved": + return "Request approved"; + case "rejected": + return "Request rejected"; + } +} + +// Or with default case for exhaustiveness checking +function handleStatusWithDefault(status: Status) { + switch (status) { + case "pending": + return "Waiting for approval"; + case "approved": + return "Request approved"; + case "rejected": + return "Request rejected"; + default: + const _exhaustiveCheck: never = status; + return _exhaustiveCheck; + } +} + +enum Color { + Red, + Green, + Blue, +} + +function getColorName(color: Color) { + switch (color) { + case Color.Red: + return "red"; + case Color.Green: + return "green"; + case Color.Blue: + return "blue"; + default: + const _exhaustiveCheck: never = color; + return _exhaustiveCheck; + } +} +``` + +## How to use + +To **enable** this rule in the CLI or using the config file, you can use: + +::: code-group + +```bash [CLI] +oxlint --deny typescript/switch-exhaustiveness-check +``` + +```json [Config (.oxlintrc.json)] +{ + "rules": { + "typescript/switch-exhaustiveness-check": "error" + } +} +``` + +::: + +## References + +- Rule Source diff --git a/src/docs/guide/usage/linter/rules/typescript/unbound-method.md b/src/docs/guide/usage/linter/rules/typescript/unbound-method.md new file mode 100644 index 0000000000..42b55ce6a5 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/typescript/unbound-method.md @@ -0,0 +1,121 @@ + + + + +# typescript/unbound-method + +
+ + This rule is turned on by default. + + +🚧 An auto-fix is still under development. + +
+ +### What it does + +This rule enforces unbound methods are called with their expected scope. + +### Why is this bad? + +When you extract a method from an object and call it separately, the `this` context is lost. This can lead to runtime errors or unexpected behavior, especially with methods that rely on `this` to access instance properties or other methods. + +### Examples + +Examples of **incorrect** code for this rule: + +```ts +class MyClass { + private value = 42; + + getValue() { + return this.value; + } + + processValue() { + return this.value * 2; + } +} + +const instance = new MyClass(); + +// Unbound method - loses 'this' context +const getValue = instance.getValue; +getValue(); // Runtime error: cannot read property 'value' of undefined + +// Passing unbound method as callback +[1, 2, 3].map(instance.processValue); // 'this' will be undefined + +// Destructuring methods +const { getValue: unboundGetValue } = instance; +unboundGetValue(); // Runtime error +``` + +Examples of **correct** code for this rule: + +```ts +class MyClass { + private value = 42; + + getValue() { + return this.value; + } + + processValue() { + return this.value * 2; + } +} + +const instance = new MyClass(); + +// Call method on instance +const value = instance.getValue(); // Correct + +// Bind method to preserve context +const boundGetValue = instance.getValue.bind(instance); +boundGetValue(); // Correct + +// Use arrow function to preserve context +[1, 2, 3].map(() => instance.processValue()); // Correct + +// Use arrow function in class for auto-binding +class MyClassWithArrow { + private value = 42; + + getValue = () => { + return this.value; + }; +} + +const instance2 = new MyClassWithArrow(); +const getValue = instance2.getValue; // Safe - arrow function preserves 'this' +getValue(); // Correct +``` + +## How to use + +To **enable** this rule in the CLI or using the config file, you can use: + +::: code-group + +```bash [CLI] +oxlint --deny typescript/unbound-method +``` + +```json [Config (.oxlintrc.json)] +{ + "rules": { + "typescript/unbound-method": "error" + } +} +``` + +::: + +## References + +- Rule Source diff --git a/src/docs/guide/usage/linter/rules/typescript/use-unknown-in-catch-callback-variable.md b/src/docs/guide/usage/linter/rules/typescript/use-unknown-in-catch-callback-variable.md new file mode 100644 index 0000000000..f303cf44d3 --- /dev/null +++ b/src/docs/guide/usage/linter/rules/typescript/use-unknown-in-catch-callback-variable.md @@ -0,0 +1,111 @@ + + + + +# typescript/use-unknown-in-catch-callback-variable + +
+ +🚧 An auto-fix is still under development. + +
+ +### What it does + +This rule enforces using `unknown` for catch clause variables instead of `any`. + +### Why is this bad? + +In TypeScript 4.0+, catch clause variables can be typed as `unknown` instead of `any`. Using `unknown` is safer because it forces you to perform type checking before using the error, preventing potential runtime errors. + +### Examples + +Examples of **incorrect** code for this rule: + +```ts +try { + somethingRisky(); +} catch (error: any) { // Should use 'unknown' + console.log(error.message); // Unsafe access + error.someMethod(); // Unsafe call +} + +// Default catch variable is 'any' in older TypeScript +try { + somethingRisky(); +} catch (error) { // Implicitly 'any' + console.log(error.message); // Unsafe access +} +``` + +Examples of **correct** code for this rule: + +```ts +try { + somethingRisky(); +} catch (error: unknown) { + // Type guard for Error objects + if (error instanceof Error) { + console.log(error.message); // Safe access + console.log(error.stack); + } else { + console.log("Unknown error:", error); + } +} + +// More comprehensive error handling +try { + somethingRisky(); +} catch (error: unknown) { + if (error instanceof Error) { + // Handle Error objects + console.error("Error:", error.message); + } else if (typeof error === "string") { + // Handle string errors + console.error("String error:", error); + } else { + // Handle unknown error types + console.error("Unknown error type:", error); + } +} + +// Helper function for error handling +function isError(error: unknown): error is Error { + return error instanceof Error; +} + +try { + somethingRisky(); +} catch (error: unknown) { + if (isError(error)) { + console.log(error.message); + } +} +``` + +## How to use + +To **enable** this rule in the CLI or using the config file, you can use: + +::: code-group + +```bash [CLI] +oxlint --deny typescript/use-unknown-in-catch-callback-variable +``` + +```json [Config (.oxlintrc.json)] +{ + "rules": { + "typescript/use-unknown-in-catch-callback-variable": "error" + } +} +``` + +::: + +## References + +- Rule Source diff --git a/src/docs/guide/usage/linter/rules/version.data.js b/src/docs/guide/usage/linter/rules/version.data.js index 95fe5b8661..4581836798 100644 --- a/src/docs/guide/usage/linter/rules/version.data.js +++ b/src/docs/guide/usage/linter/rules/version.data.js @@ -1,5 +1,5 @@ export default { load() { - return "c461a862f371fc73f6307e3a99964ba15d687b3b"; + return "66a350eba5cadfa0df0fb9f90c848090531aadfc"; }, };