{"record":{"id":"75dc694988b5d092","repo":"oxc-project/oxc","slug":"use-set-size-instead-of-converting-a-set-to-an","errorCode":null,"errorMessage":"Use `Set#size` instead of converting a `Set` to an array and using its `length` property.","messagePattern":"Use `Set#size` instead of converting a `Set` to an array and using its `length` property\\.","errorType":"validation","errorClass":"OxcDiagnostic","httpStatus":null,"severity":"warning","filePath":"crates/oxc_linter/src/rules/unicorn/prefer_set_size.rs","lineNumber":20,"sourceCode":"    AstKind,\n    ast::{ArrayExpressionElement, CallExpression, Expression},\n};\nuse oxc_diagnostics::OxcDiagnostic;\nuse oxc_macros::declare_oxc_lint;\nuse oxc_semantic::IsGlobalReference;\nuse oxc_span::{GetSpan, Span};\n\nuse crate::{\n    AstNode,\n    ast_util::variable_declaration_kind,\n    ast_util::{get_declaration_of_variable, is_method_call},\n    context::LintContext,\n    fixer::Fix,\n    rule::Rule,\n};\n\nfn prefer_set_size_diagnostic(span: Span) -> OxcDiagnostic {\n    OxcDiagnostic::warn(\n        \"Use `Set#size` instead of converting a `Set` to an array and using its `length` property.\",\n    )\n    .with_label(span)\n}\n\n#[derive(Debug, Default, Clone)]\npub struct PreferSetSize;\n\ndeclare_oxc_lint!(\n    /// ### What it does\n    ///\n    /// Prefer `Set#size` over `Set#length` when the `Set` is converted to an array.\n    ///\n    /// ### Why is this bad?\n    ///\n    /// Using `Set#size` is more readable and performant.\n    ///\n    /// ### Examples","sourceCodeStart":2,"sourceCodeEnd":38,"githubUrl":"https://github.com/oxc-project/oxc/blob/a3d33dda7cb69da23db4fcaa2c0c05de61e760a1/crates/oxc_linter/src/rules/unicorn/prefer_set_size.rs#L2-L38","documentation":"This is the oxlint rule `unicorn/prefer-set-size`. It flags code that converts a `Set` to an array solely to read its `length` (e.g. `[...set].length` or `Array.from(set).length`) when the `Set` already exposes its element count as `Set#size`. The rule uses `get_declaration_of_variable` to trace the receiver back to a Set-producing expression before reporting.","triggerScenarios":"`[...set].length`, `Array.from(set).length`, or the same pattern through an intermediate variable declared as `[...set]` / `Array.from(set)` whose only use is `.length`. The rule recognizes the method call via `is_method_call` and checks the declaration with `get_declaration_of_variable`.","commonSituations":"Code written before `Set#size` was widely known, or converted from arrays to Sets without updating count reads; also snapshot/telemetry code like `expect(Array.from(ids).length).toBe(3)`.","solutions":["Replace the whole expression with `set.size`.","If the array conversion is needed for other reasons (logging, iteration), read the count from the Set separately instead of chaining `.length` on the conversion.","Apply the provided fix via `oxlint --fix`, which rewrites the span to `set.size`."],"exampleFix":"// before\nconst count = [...uniqueIds].length;\n\n// after\nconst count = uniqueIds.size;","handlingStrategy":"validation","validationCode":"// Read sizes from the source structure directly\nconst n = uniqueIds.size; // not [...uniqueIds].length\nconsole.assert(Number.isInteger(n), 'size must be an integer');","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Memorize the Set/Map accessors: `.size` (not `.length`), `.has` (not `.includes`).","When converting array code to Set code, grep for `.length` on converted identifiers the same commit.","Let `oxlint --fix` apply the rewrite; the fix is local and safe."],"tags":["oxlint","unicorn","set","style","refactor"],"backgroundTag":"set-size-vs-array-length","analyzedSha":"a3d33dda7cb69da23db4fcaa2c0c05de61e760a1","analyzedAt":"2026-08-20T07:01:07.079Z","contentChangedAt":"2026-08-20T07:01:07.079Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}