{"record":{"id":"ae6de74c9d74240d","repo":"oxc-project/oxc","slug":"prefer-class-field-declaration-over-this-assignm","errorCode":null,"errorMessage":"Prefer class field declaration over `this` assignment in constructor for static values.","messagePattern":"Prefer class field declaration over `this` assignment in constructor for static values\\.","errorType":"validation","errorClass":"OxcDiagnostic","httpStatus":null,"severity":"warning","filePath":"crates/oxc_linter/src/rules/unicorn/prefer_class_fields.rs","lineNumber":15,"sourceCode":"use oxc_ast::{\n    AstKind,\n    ast::{\n        AssignmentExpression, AssignmentOperator, ClassElement, Expression, MemberExpression,\n        MethodDefinitionKind, PropertyDefinitionType, Statement,\n    },\n};\nuse oxc_diagnostics::OxcDiagnostic;\nuse oxc_macros::declare_oxc_lint;\nuse oxc_span::{GetSpan, Span};\n\nuse crate::{AstNode, context::LintContext, rule::Rule};\n\nfn prefer_class_fields_diagnostic(span: Span) -> OxcDiagnostic {\n    OxcDiagnostic::warn(\n        \"Prefer class field declaration over `this` assignment in constructor for static values.\",\n    )\n    .with_help(\"Declare static values as class fields instead of assigning them to `this` in the constructor.\")\n    .with_label(span)\n}\n\nfn prefer_class_fields_suggestion(span: Span) -> OxcDiagnostic {\n    OxcDiagnostic::warn(\n        \"Encountered same-named class field declaration and `this` assignment in constructor.\",\n    )\n    .with_help(\"Replace the class field declaration with the value from `this` assignment.\")\n    .with_label(span)\n}\n\n#[derive(Debug, Default, Clone)]\npub struct PreferClassFields;\n\ndeclare_oxc_lint!(","sourceCodeStart":1,"sourceCodeEnd":33,"githubUrl":"https://github.com/oxc-project/oxc/blob/e1e7af627c8843ab64044ed466b128fcc21a035b/crates/oxc_linter/src/rules/unicorn/prefer_class_fields.rs#L1-L33","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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)."],"exampleFix":"// before\nclass Client {\n  constructor() {\n    this.retries = 3;\n    this.cache = new Map();\n  }\n}\n\n// after\nclass Client {\n  retries = 3;\n  cache = new Map();\n}","handlingStrategy":"validation","validationCode":"// oxlint --filter unicorn/prefer-class-fields src/\n// CI gate: oxlint --deny-warnings src/","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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."],"tags":["oxlint","unicorn","classes","modernization","refactor"],"backgroundTag":"lint-rule-violation","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"}