oxc-project/oxc · warning · OxcDiagnostic
Prefer class field declaration over `this` assignment in con
Error message
Prefer class field declaration over `this` assignment in constructor for static values.
What it means
Lint diagnostic from oxlint's `unicorn/prefer-class-fields` rule (main variant). Assigning constant values to `this.x` in the constructor (`this.timeout = 5000;`) is the pre-class-fields way to initialize instance state; class field declarations (`timeout = 5000;`) express it directly on the class, work with subclasses/field ordering, and remove constructor boilerplate. The rule flags `this` assignments of static values in constructors.
Source
Thrown at crates/oxc_linter/src/rules/unicorn/prefer_class_fields.rs:15
use oxc_ast::{
AstKind,
ast::{
AssignmentExpression, AssignmentOperator, ClassElement, Expression, MemberExpression,
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!(View on GitHub (pinned to e1e7af627c)
Solutions
- Move the assignment out of the constructor into a field declaration: `retries = 3;` at class top level.
- Run `oxlint --fix` for the mechanical move; review when inheritance is involved.
- Keep `this.x = param` assignments (parameter-dependent) — the rule only targets static values; suppress inline for computed-by-side-effect initializers.
- Disable the rule if the build target does not support class fields (very old transpiler configs).
Example fix
// before
class Client {
constructor() {
this.retries = 3;
this.cache = new Map();
}
}
// after
class Client {
retries = 3;
cache = new Map();
} Defensive patterns
Strategy: validation
Validate before calling
// oxlint --filter unicorn/prefer-class-fields src/ // CI gate: oxlint --deny-warnings src/
Prevention
- Initialize constant state as class fields; keep only parameter-dependent assignments in constructors.
- After migrating, run the test suite — TS `useDefineForClassFields`/target changes can alter property semantics.
- Update older classes opportunistically during touch, so the rule never accumulates a backlog.
When it happens
Trigger: A constructor containing `this.<name> = <literal or static expression>;` where the value does not depend on constructor parameters — e.g. `constructor() { this retries = 3; this.cache = new Map(); }`. Detected while oxlint walks AssignmentExpression nodes that target `this.X` inside constructors.
Common situations: Classes written before the class-fields proposal (or ported from TypeScript configs with `useDefineForClassFields` concerns). Teams adopting oxlint's unicorn category see this on service/utility classes. Watch version changes: switching `target`/`useDefineForClassFields` in TS alters field semantics (define vs set), so the autofix can change behavior when a parent class defines the same property.
Related errors
- Encountered same-named class field declaration and `this` as
- Unnecessary `.getTime()` call
- Invalid class name, use `{expected}`.
- Missing call to `super()` in constructor.
- The `name` property should be set to `{name}`.
AI-assisted analysis of oxc-project/oxc@e1e7af627c (2026-08-20).
Data as JSON: /api/errors/ae6de74c9d74240d.
Report an issue: GitHub.