oxc-project/oxc · warning · OxcDiagnostic
Disallow using `Object.assign` with an object literal as the
Error message
Disallow using `Object.assign` with an object literal as the first argument and prefer the use of object spread instead
What it means
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 }`).
Source
Thrown at crates/oxc_linter/src/rules/eslint/prefer_object_spread.rs:18
use std::cmp::max;
use oxc_allocator::ArenaBox;
use oxc_ast::AstKind;
use oxc_ast::ast::{Expression, ObjectExpression, ObjectPropertyKind, PropertyKind};
use oxc_diagnostics::OxcDiagnostic;
use oxc_macros::declare_oxc_lint;
use oxc_span::{GetSpan, Span};
use crate::{AstNode, ast_util::is_method_call, context::LintContext, rule::Rule};
fn prefer_object_spread_diagnostic(span: Span, for_use_literal: bool) -> OxcDiagnostic {
let help_message = if for_use_literal {
"Use an object literal instead of `Object.assign`. eg: `{ foo: bar }`."
} else {
"Use an object spread instead of `Object.assign` eg: `{ ...foo }`."
};
OxcDiagnostic::warn("Disallow using `Object.assign` with an object literal as the first argument and prefer the use of object spread instead")
.with_help(help_message)
.with_label(span)
}
#[derive(Debug, Default, Clone)]
pub struct PreferObjectSpread;
declare_oxc_lint!(
/// ### What it does
///
/// Disallow using `Object.assign` with an object literal as the first argument and prefer the use of object spread instead.
///
/// ### Why is this bad?
///
/// 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.
///
/// ### Examples
///View on GitHub (pinned to e1e7af627c)
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.
Example fix
// before
const merged = Object.assign({}, defaults, userOptions);
// after
const merged = { ...defaults, ...userOptions }; Defensive patterns
Strategy: validation
Validate before calling
// spread is supported everywhere ES2018+; verify target before enabling // browserslist: "> 0.5%, not dead, not op_mini all"
Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Capture group should be named.
- Disallow use of `Object.prototype.hasOwnProperty.call()` and
- Prefer `**` over `Math.pow`.
- Use {prefix_name} literals instead of parseInt().
- Use the rest parameters instead of `arguments`.
AI-assisted analysis of oxc-project/oxc@e1e7af627c (2026-08-20).
Data as JSON: /api/errors/6d719f639192475a.
Report an issue: GitHub.