oxc-project/oxc · warning · OxcDiagnostic

Unnecessarily computed property `{key}` found.

Error message

Unnecessarily computed property `{key}` found.

What it means

Diagnostic from the `no-useless-computed-key` rule. An object literal or class member uses computed key syntax `{["key"]: value}` where the expression is a plain string/number literal, so the brackets add nothing over the direct key syntax. Oxc reports the span and, per the diagnostic builder, uses the literal (or an empty Str fallback) in the message.

Source

Thrown at crates/oxc_linter/src/rules/eslint/no_useless_computed_key.rs:21

use oxc_macros::declare_oxc_lint;
use oxc_span::{GetSpan, Span};
use oxc_str::Str;
use schemars::JsonSchema;
use serde::Deserialize;
use serde_json::Value;

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

fn no_useless_computed_key_diagnostic(span: Span, raw: Option<Str>) -> OxcDiagnostic {
    // false positive, if we remove the closure, `borrowed data escapes outside of function `raw` escapes the function body here`
    #[expect(clippy::redundant_closure)]
    let key = raw.unwrap_or_else(|| Str::empty());
    OxcDiagnostic::warn(format!("Unnecessarily computed property `{key}` found."))
        .with_help("Replace the computed property with a plain identifier or string literal")
        .with_label(span)
}

#[derive(Debug, Clone, JsonSchema, Deserialize)]
#[serde(rename_all = "camelCase", default, deny_unknown_fields)]
pub struct NoUselessComputedKey {
    /// The `enforceForClassMembers` option controls whether the rule applies to
    /// class members (methods and properties).
    ///
    /// Examples of **correct** code for this rule with the `{ "enforceForClassMembers": false }` option:
    /// ```js
    /// class SomeClass {
    ///     ["foo"] = "bar";
    ///     [42] = "baz";
    ///     get ['b']() {}
    ///     set ['c'](value) {}
    ///     static ["foo"] = "bar";

View on GitHub (pinned to e1e7af627c)

Solutions

  1. Drop the brackets and quotes for identifier-safe keys: `{ ["foo"]: 1 }` -> `{ foo: 1 }`.
  2. For numeric keys use plain `{ 42: 'x' }`.
  3. For keys needing quotes (spaces, reserved words) write `{ 'foo bar': 1 }` without brackets.
  4. Let `oxlint --fix` apply the suggested replacement (the rule pads fixes with token boundaries).

Example fix

// before
const obj = { ["foo"]: 1, ['bar']: 2 };

// after
const obj = { foo: 1, bar: 2 };
Defensive patterns

Strategy: validation

Validate before calling

const hasStaticComputedKey = /\[\s*(['"][^'"]+['"]|\d+)\s*\]/.test(sourceSnippet);

Prevention

When it happens

Trigger: Writing `{ ["foo"]: 1 }`, `{ [42]: 'x' }`, or `class A { ["bar"]() {} }`. The rule also honors the `enforceForClassMembers` option (default applies to object literals; set it to cover class members). Dynamic keys like `{ [Symbol.iterator]: fn }` or `{ [prefix + 'x']: 1 }` are not flagged.

Common situations: Code generated from templates or JSON-to-JS converters that always emit computed keys; refactors that removed a dynamic expression but left the brackets; copy-paste from code that legitimately used symbols.

Related errors


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