{"record":{"id":"6d719f639192475a","repo":"oxc-project/oxc","slug":"disallow-using-object-assign-with-an-object-lite","errorCode":null,"errorMessage":"Disallow using `Object.assign` with an object literal as the first argument and prefer the use of object spread instead","messagePattern":"Disallow using `Object\\.assign` with an object literal as the first argument and prefer the use of object spread instead","errorType":"validation","errorClass":"OxcDiagnostic","httpStatus":null,"severity":"warning","filePath":"crates/oxc_linter/src/rules/eslint/prefer_object_spread.rs","lineNumber":18,"sourceCode":"use std::cmp::max;\n\nuse oxc_allocator::ArenaBox;\nuse oxc_ast::AstKind;\nuse oxc_ast::ast::{Expression, ObjectExpression, ObjectPropertyKind, PropertyKind};\nuse oxc_diagnostics::OxcDiagnostic;\nuse oxc_macros::declare_oxc_lint;\nuse oxc_span::{GetSpan, Span};\n\nuse crate::{AstNode, ast_util::is_method_call, context::LintContext, rule::Rule};\n\nfn prefer_object_spread_diagnostic(span: Span, for_use_literal: bool) -> OxcDiagnostic {\n    let help_message = if for_use_literal {\n        \"Use an object literal instead of `Object.assign`. eg: `{ foo: bar }`.\"\n    } else {\n        \"Use an object spread instead of `Object.assign` eg: `{ ...foo }`.\"\n    };\n    OxcDiagnostic::warn(\"Disallow using `Object.assign` with an object literal as the first argument and prefer the use of object spread instead\")\n        .with_help(help_message)\n        .with_label(span)\n}\n\n#[derive(Debug, Default, Clone)]\npub struct PreferObjectSpread;\n\ndeclare_oxc_lint!(\n    /// ### What it does\n    ///\n    /// Disallow using `Object.assign` with an object literal as the first argument and prefer the use of object spread instead.\n    ///\n    /// ### Why is this bad?\n    ///\n    /// When `Object.assign` is called using an object literal as the first argument, this rule requires using the object spread syntax instead. This rule also warns on cases where an `Object.assign` call is made using a single argument that is an object literal, in this case, the `Object.assign` call is not needed.\n    ///\n    /// ### Examples\n    ///","sourceCodeStart":1,"sourceCodeEnd":36,"githubUrl":"https://github.com/oxc-project/oxc/blob/e1e7af627c8843ab64044ed466b128fcc21a035b/crates/oxc_linter/src/rules/eslint/prefer_object_spread.rs#L1-L36","documentation":"Diagnostic from the oxlint `prefer-object-spread` rule. It fires when `Object.assign` is called with an object literal as the first argument, since ES2018 object spread does the same without the intermediate literal mutation semantics (prefer_object_spread.rs:18-27). The help text distinguishes two shapes: spreading into a fresh literal (`for_use_literal` false, `{ ...foo }`) versus rebuilding a literal target (`{ foo: bar }`).","triggerScenarios":"Enable the rule and write `Object.assign({}, defaults, overrides)` (literal first arg, spread suggested) or `Object.assign({ foo: bar }, source)` (literal-rebuild suggested). Calls whose first argument is not an object literal, e.g. `Object.assign(target, src)`, are not reported by this message path.","commonSituations":"Options-merging code written before ES2018 spread; tutorial-style `Object.assign({}, state, patch)` in Redux reducers; runtimes or transpilers lacking spread support (old targets); getters on the source being copied — spread copies values like Object.assign, so semantics match, but note spread does not trigger setters on the target the same way in edge cases.","solutions":["Replace with spread: `Object.assign({}, a, b)` becomes `{ ...a, ...b }` (auto-fixable).","For the literal-target shape, inline the literal: `Object.assign({ foo: bar }, src)` becomes `{ foo: bar, ...src }`.","Keep Object.assign only when mutating an existing non-literal target is intentional — those calls are not flagged here.","Disable the rule for build targets that lack spread support."],"exampleFix":"// before\nconst merged = Object.assign({}, defaults, userOptions);\n\n// after\nconst merged = { ...defaults, ...userOptions };","handlingStrategy":"validation","validationCode":"// spread is supported everywhere ES2018+; verify target before enabling\n// browserslist: \"> 0.5%, not dead, not op_mini all\"","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use `{ ...a, ...b }` instead of `Object.assign({}, a, b)` in new code.","Reserve `Object.assign(target, ...)` for intentionally mutating an existing target — that shape is not flagged.","Run `oxlint --fix` when adopting the rule; literal-first calls convert mechanically."],"tags":["oxlint","eslint","es2018","objects","spread","modernization"],"backgroundTag":"eslint-object-spread","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"}