oxc-project/oxc · warning · OxcDiagnostic

Encountered same-named class field declaration and `this` as

Error message

Encountered same-named class field declaration and `this` assignment in constructor.

What it means

Lint diagnostic from oxlint's `unicorn/prefer-class-fields` rule (suggestion variant). It fires in the narrower case where the class ALREADY declares a field `x = <something>` AND the constructor assigns `this.x = <other>` with the same name — the field initializer is immediately overwritten, so the declaration value is dead. The suggested fix is to fold the constructor value into the field declaration and drop the assignment.

Source

Thrown at crates/oxc_linter/src/rules/unicorn/prefer_class_fields.rs:23

        MethodDefinitionKind, PropertyDefinitionType, Statement,
    },
};
use oxc_diagnostics::OxcDiagnostic;
use oxc_macros::declare_oxc_lint;
use oxc_span::{GetSpan, Span};

use crate::{AstNode, context::LintContext, rule::Rule};

fn prefer_class_fields_diagnostic(span: Span) -> OxcDiagnostic {
    OxcDiagnostic::warn(
        "Prefer class field declaration over `this` assignment in constructor for static values.",
    )
    .with_help("Declare static values as class fields instead of assigning them to `this` in the constructor.")
    .with_label(span)
}

fn prefer_class_fields_suggestion(span: Span) -> OxcDiagnostic {
    OxcDiagnostic::warn(
        "Encountered same-named class field declaration and `this` assignment in constructor.",
    )
    .with_help("Replace the class field declaration with the value from `this` assignment.")
    .with_label(span)
}

#[derive(Debug, Default, Clone)]
pub struct PreferClassFields;

declare_oxc_lint!(
    /// ### What it does
    ///
    /// Prefers class field declarations over `this` assignments in constructors for static values.
    ///
    /// ### Why is this bad?
    ///
    /// Class field declarations are more readable and less error-prone than assigning static
    /// values to `this` in the constructor. Using class fields keeps the constructor cleaner

View on GitHub (pinned to e1e7af627c)

Solutions

  1. Merge: `count = 1;` as the field and delete `this.count = 1;` from the constructor.
  2. If the assignment is conditional (e.g. `if (opts) this.count = opts.count`), keep the constructor assignment but make the field the documented default; suppress with `// oxlint-disable-next-line unicorn/prefer-class-fields` and a comment.
  3. Run `oxlint --fix` and verify tests, since initialization order in subclasses can change.
  4. Disable the rule only if class-field semantics are deliberately being avoided repo-wide.

Example fix

// before
class Counter {
  count = 0;
  constructor() {
    this.count = 1;
  }
}

// after
class Counter {
  count = 1;
}
Defensive patterns

Strategy: validation

Validate before calling

// oxlint --filter unicorn/prefer-class-fields src/
// CI gate: oxlint --deny-warnings src/

Prevention

When it happens

Trigger: `class A { count = 0; constructor() { this.count = 1; } }` — same-named PropertyDefinition and `this.` assignment in the constructor. Reported during oxlint analysis of constructors that assign to declared field names.

Common situations: Partial migrations: someone added class fields but left old constructor assignments; or subclasses that re-assign inherited fields. The duplicated initialization is a real smell — the field initializer runs first and is discarded. Common during incremental modernization passes flagged in bulk by unicorn.

Related errors


AI-assisted analysis of oxc-project/oxc@e1e7af627c (2026-08-20). Data as JSON: /api/errors/89358e7c6d161967. Report an issue: GitHub.