{"record":{"id":"a24ec7b84b84c055","repo":"oxc-project/oxc","slug":"redundant-double-negation","errorCode":null,"errorMessage":"Redundant double negation","messagePattern":"Redundant double negation","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"crates/oxc_linter/src/rules/eslint/no_extra_boolean_cast.rs","lineNumber":27,"sourceCode":"    },\n};\nuse oxc_diagnostics::OxcDiagnostic;\nuse oxc_macros::declare_oxc_lint;\nuse oxc_span::{GetSpan, Span};\nuse oxc_syntax::{\n    operator::{LogicalOperator, UnaryOperator},\n    precedence::{GetPrecedence, Precedence},\n};\n\nuse crate::{\n    AstNode,\n    context::LintContext,\n    rule::{DefaultRuleConfig, Rule},\n    utils::{get_precedence, pad_fix_with_token_boundary},\n};\n\nfn no_extra_double_negation_cast_diagnostic(span: Span) -> OxcDiagnostic {\n    OxcDiagnostic::warn(\"Redundant double negation\")\n        .with_help(\"Remove the double negation as it will already be coerced to a boolean\")\n        .with_label(span)\n}\n\nfn no_extra_boolean_cast_diagnostic(span: Span) -> OxcDiagnostic {\n    OxcDiagnostic::warn(\"Redundant Boolean call\")\n        .with_help(\"Remove the Boolean call as it will already be coerced to a boolean\")\n        .with_label(span)\n}\n\n#[derive(Debug, Default, Clone, JsonSchema, Deserialize)]\n#[serde(rename_all = \"camelCase\", default, deny_unknown_fields)]\npub struct NoExtraBooleanCast {\n    /// when set to `true`, in addition to checking default contexts, checks\n    /// whether extra boolean casts are present in expressions whose result is\n    /// used in a boolean context. See examples below. Default is `false`,\n    /// meaning that this rule by default does not warn about extra booleans\n    /// cast inside inner expressions.","sourceCodeStart":9,"sourceCodeEnd":45,"githubUrl":"https://github.com/oxc-project/oxc/blob/e1e7af627c8843ab64044ed466b128fcc21a035b/crates/oxc_linter/src/rules/eslint/no_extra_boolean_cast.rs#L9-L45","documentation":"This diagnostic comes from the `no_extra_boolean_cast` rule in oxlint. It reports a double negation `!!x` in a place where the value is already coerced to a boolean: an `if` test, a loop condition, a ternary test, a logical operand, or under another negation. The rule ships a fixer, so `oxlint --fix` can strip the cast with correct token boundaries. A second message, `Redundant Boolean call`, covers the `Boolean(x)` form.","triggerScenarios":"`if (!!items.length) { ... }`, `while (!!pending) { ... }`, a ternary test `!!x ? a : b`, or a logical operand `x || !!y`. Assignments such as `const ok = !!x;` are boolean-producing spots and stay valid.","commonSituations":"A C-style habit of double negation. Code moves from a boolean variable assignment into a condition, and the cast travels along. Mixed team styles after a merge.","solutions":["Delete the `!!` inside the condition; the context already coerces to boolean.","Keep `!!` only at assignments that must store a real boolean: `const ok = !!x;`.","Run `oxlint --fix` to strip redundant casts automatically.","Suppress with `// oxlint-disable-next-line no-extra-boolean-cast` when the cast is deliberate."],"exampleFix":"// before\nif (!!options.verbose) {\n  log('starting');\n}\n\n// after\nif (options.verbose) {\n  log('starting');\n}","handlingStrategy":"validation","validationCode":"// find double negation used inside conditions\nif (/(?:if|while)\\s*\\(\\s*!!/.test(src)) console.warn('redundant double negation in condition');","typeGuard":"const isBoolean = (v: unknown): v is boolean => typeof v === 'boolean';","tryCatchPattern":null,"preventionTips":["Apply `!!` or `Boolean()` only at assignments, never inside a condition.","Run `oxlint --fix` after merges to strip casts in bulk.","Write the condition as the expression itself; do not pre-cast it."],"tags":["javascript","eslint","lint","boolean","autofix"],"backgroundTag":"lint-redundant-boolean-cast","analyzedSha":"e1e7af627c8843ab64044ed466b128fcc21a035b","analyzedAt":"2026-08-20T07:01:07.079Z","contentChangedAt":"2026-08-20T07:01:07.079Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}