diff --git a/.changeset/dirty-beans-flash.md b/.changeset/dirty-beans-flash.md new file mode 100644 index 000000000000..ece492d9913c --- /dev/null +++ b/.changeset/dirty-beans-flash.md @@ -0,0 +1,5 @@ +--- +"@biomejs/biome": minor +--- + +Closes [#8024](https://github.com/biomejs/biome/issues/8024). Adds the `checkForEach` option to [useIterableCallbackReturn](https://biomejs.dev/linter/rules/use-iterable-callback-return/) allowing `forEach()` callbacks to be skipped from being checked for returning a value. diff --git a/crates/biome_js_analyze/src/lint/suspicious/use_iterable_callback_return.rs b/crates/biome_js_analyze/src/lint/suspicious/use_iterable_callback_return.rs index 6ce5644d2b9f..c493ae95a457 100644 --- a/crates/biome_js_analyze/src/lint/suspicious/use_iterable_callback_return.rs +++ b/crates/biome_js_analyze/src/lint/suspicious/use_iterable_callback_return.rs @@ -80,6 +80,23 @@ declare_lint_rule! { /// ```js /// [].forEach(() => void null); // Void return value, which doesn't trigger the rule /// ``` + /// + /// ## Options + /// + /// ### `checkForEach` + /// + /// Default: `true` + /// + /// When set to `false`, rule will skip reporting `forEach` callbacks that return a value. + /// + /// ```json,options + /// { + /// "options": { + /// "checkForEach": true + /// } + /// } + /// ``` + /// pub UseIterableCallbackReturn { version: "2.0.0", name: "useIterableCallbackReturn", @@ -128,6 +145,10 @@ impl Rule for UseIterableCallbackReturn { .and_then(|member| member.as_js_name().cloned()) .and_then(|name| name.value_token().ok())?; + if !ctx.options().check_for_each() && member_name.text_trimmed() == "forEach" { + return None; + } + let method_config = ITERABLE_METHOD_INFOS.get(member_name.text_trimmed())?; let arg_position = argument_list diff --git a/crates/biome_rule_options/src/use_iterable_callback_return.rs b/crates/biome_rule_options/src/use_iterable_callback_return.rs index 866a2b0db3b3..3e8ff519773e 100644 --- a/crates/biome_rule_options/src/use_iterable_callback_return.rs +++ b/crates/biome_rule_options/src/use_iterable_callback_return.rs @@ -3,4 +3,18 @@ use serde::{Deserialize, Serialize}; #[derive(Default, Clone, Debug, Deserialize, Deserializable, Merge, Eq, PartialEq, Serialize)] #[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] #[serde(rename_all = "camelCase", deny_unknown_fields, default)] -pub struct UseIterableCallbackReturnOptions {} +pub struct UseIterableCallbackReturnOptions { + /// When set to `false`, rule will skip reporting `forEach` callbacks that return a value. + #[serde(skip_serializing_if = "Option::<_>::is_none")] + pub check_for_each: Option, +} + +impl UseIterableCallbackReturnOptions { + pub const DEFAULT_CHECK_FOR_EACH: bool = true; + + /// Returns [`Self::check_for_each`] if it is set. + /// Otherwise, returns [`Self::DEFAULT_CHECK_FOR_EACH`]. + pub fn check_for_each(&self) -> bool { + self.check_for_each.unwrap_or(Self::DEFAULT_CHECK_FOR_EACH) + } +} diff --git a/packages/@biomejs/backend-jsonrpc/src/workspace.ts b/packages/@biomejs/backend-jsonrpc/src/workspace.ts index bb7ae96540d4..c931468d9491 100644 --- a/packages/@biomejs/backend-jsonrpc/src/workspace.ts +++ b/packages/@biomejs/backend-jsonrpc/src/workspace.ts @@ -8721,7 +8721,12 @@ export interface UseGetterReturnOptions {} export interface UseGoogleFontDisplayOptions {} export interface UseGuardForInOptions {} export interface UseIsArrayOptions {} -export interface UseIterableCallbackReturnOptions {} +export interface UseIterableCallbackReturnOptions { + /** + * When set to `false`, rule will skip reporting `forEach` callbacks that return a value. + */ + checkForEach?: boolean; +} export interface UseNamespaceKeywordOptions {} export interface UseNumberToFixedDigitsArgumentOptions {} export interface UseStaticResponseMethodsOptions {} diff --git a/packages/@biomejs/biome/configuration_schema.json b/packages/@biomejs/biome/configuration_schema.json index 6d5bba373965..d8aa50709bc7 100644 --- a/packages/@biomejs/biome/configuration_schema.json +++ b/packages/@biomejs/biome/configuration_schema.json @@ -14510,6 +14510,12 @@ }, "UseIterableCallbackReturnOptions": { "type": "object", + "properties": { + "checkForEach": { + "description": "When set to `false`, rule will skip reporting `forEach` callbacks that return a value.", + "type": ["boolean", "null"] + } + }, "additionalProperties": false }, "UseJsonImportAttributesConfiguration": {