fixhunt

eslint no-useless-computed-key

labelled safe
Runs / 2026-10-22T18-21-23-107Z-z8j8-eslint-no-useless-computed-keyeslint 9.39.52026-10-22 18:21 UTC8 programs × 2 round(s)16 programs, 8 fired, 7 fixed, 0 findings, 1 rejectedmodel cost $0.0029

Analysis Nemotron 3 Super

Flags unnecessary computed property keys using string/numeric literals that can be replaced with literal property keys.

Fix: Replace computed property key ["literal"] with "literal" (quoted string) or [number] with number (unquoted numeric literal), preserving spacing and syntax structure.

8 hazards
  • Rewriting ["__proto__"] to "__proto__" changes behavior from defining a property named "__proto__" to setting the object's prototype, altering inheritance.
  • If the computed key contains an escape sequence like ["a\nb"], rewriting to "a\nb" may alter the key if the escape was not normalized in the source.
  • In class fields, rewriting ["constructor"] to "constructor" may conflict with ES6 class constructor semantics if the field is intended as a regular property.
  • Rewriting a computed key in a destructuring pattern like {[0]: foo} to {0: foo} may fail if the key is not a valid identifier and the target environment lacks numeric property support (though rare).
  • If the computed key is adjacent to a comment inside the brackets, removing the brackets may detach or lose the comment during AST rewrite.
  • In class static fields, rewriting ["prototype"] to "prototype" may cause a runtime error because static prototype is forbidden, whereas the computed form might have been intended to avoid early error (though unlikely).
  • If the object literal is used in a context where property order matters for iteration (e.g., legacy engines), changing from computed to literal key could alter enumeration order if the literal key sorts differently.
  • Rewriting ["0"] to 0 in an object key may cause issues if the code relies on the key being a string for typeof key === 'string' checks, though the property access behavior remains the same.

Programs

idresulttitlehazard
r1-p001invalidEscape sequences in computed keysIf the computed key contains an escape sequence like ["a\nb"], rewriting to "a\nb" may alter the key if the escape was not normalized in the source.
r1-p002silent prediction offNumeric keys in destructuring patterns without numeric property supportRewriting a computed key in a destructuring pattern like {[0]: foo} to {0: foo} may fail if the key is not a valid identifier and the target environment lacks numeric property support.
r1-p003silent prediction offFunction declarations inside blocks, switch cases, labeled statementsfunction declarations inside blocks, switch cases, labeled statements
r1-p004silent prediction offString vs number key distinction in typeof checksRewriting ["0"] to 0 in an object key may cause issues if the code relies on the key being a string for typeof key === 'string' checks, though the property access behavior remains the same.
r1-p005silent prediction offComputed __proto__ key altering prototypeRewriting ["__proto__"] to "__proto__" changes behavior from defining a property named "__proto__" to setting the object's prototype, altering inheritance.
r1-p006fix okLabel/break/continue control flow with computed keyslabel/break/continue control flow, finally blocks, early returns in nested blocks
r1-p007fix okTemporal dead zone after hoisting/reorderingtemporal dead zone after code is hoisted or reordered
r1-p008fix okComments attached to removed/moved codecomments attached to the removed or moved code
r2-p001silent prediction offClass field named 'constructor' conflicts with actual constructorIn class fields, rewriting ["constructor"] to "constructor" may conflict with ES6 class constructor semantics if the field is intended as a regular property.
r2-p002fix okTemporal dead zone after hoisting/reordering in destructuringtemporal dead zone after code is hoisted or reordered
r2-p003silent prediction offVar hoisting and redeclaration inside loop after usevar hoisting and re-declaration inside loops or after use
r2-p004fired, no fixComment inside brackets detached during bracket removalIf the computed key is adjacent to a comment inside the brackets, removing the brackets may detach or lose the comment during AST rewrite.
r2-p005fix okStatic block interaction with computed key rewriteclass fields, static blocks, private names, super calls
r2-p006silentException thrown during evaluation of computed key expressionexceptions thrown inside the code the fix removes or rewrites
r2-p007fix okProperty order affects enumeration in legacy enginesIf the object literal is used in a context where property order matters for iteration (e.g., legacy engines), changing from computed to literal key could alter enumeration order if the literal key sor
r2-p008fix okASI hazard: leading parenthesis after object literal without semicolonASI and semicolon-less code, leading ( or [ on the next line

Sources

r1-p001 · Escape sequences in computed keys (generated program does not parse: /home/sun/dev/diaghunt/runs/2026-10-22T18-21-2)
1const o = {'a
2b': undefined}; console.log(o.hasOwnProperty('a
3b'));
r1-p002 · Numeric keys in destructuring patterns without numeric property support
1try { ({0: x} = {0: 42}); console.log(x); } catch (e) { console.log(e.name + ': ' + e.message); }
42
r1-p003 · Function declarations inside blocks, switch cases, labeled statements
1switch(1){case 1:{function f(){return{'a':1}};console.log(f().a);}break;}
1
r1-p004 · String vs number key distinction in typeof checks
1const o = {'0': undefined}; for (let k in o) { console.log(typeof k === 'string' ? 'str' : 'num'); break; }
str
r1-p005 · Computed __proto__ key altering prototype
1const o = {'__proto__': {toString(){return 'changed'}}}, p = {}; Object.assign(p, o); console.log(p.toString());
[object Object]
r1-p006 · Label/break/continue control flow with computed keys
1outer: for (;;) { inner: { if (true) break outer; } ({['a']: x} = {a: 1}); console.log(x); break; }
--- orig.js	2026-10-22 14:21:31.215257408 -0400
+++ fixed.js	2026-10-22 14:21:34.988415139 -0400
@@ -1 +1 @@
-outer: for (;;) { inner: { if (true) break outer; } ({['a']: x} = {a: 1}); console.log(x); break; }
+outer: for (;;) { inner: { if (true) break outer; } ({'a': x} = {a: 1}); console.log(x); break; }
r1-p007 · Temporal dead zone after hoisting/reordering
1let x; ({['a']: x} = {a: 1}); console.log(x); let y = 2;
--- orig.js	2026-10-22 14:21:31.236258286 -0400
+++ fixed.js	2026-10-22 14:21:33.828366619 -0400
@@ -1 +1 @@
-let x; ({['a']: x} = {a: 1}); console.log(x); let y = 2;
+let x; ({'a': x} = {a: 1}); console.log(x); let y = 2;
1
r1-p008 · Comments attached to removed/moved code
1/* keep */ const o = {['a'] /* comment */: 1}; console.log(o.a);
--- orig.js	2026-10-22 14:21:34.879410580 -0400
+++ fixed.js	2026-10-22 14:21:38.129546643 -0400
@@ -1 +1 @@
-/* keep */ const o = {['a'] /* comment */: 1}; console.log(o.a);
+/* keep */ const o = {'a' /* comment */: 1}; console.log(o.a);
1
r2-p001 · Class field named 'constructor' conflicts with actual constructor
1class C {
2 ["constructor"] = () => {
3 console.log('field called');
4 return 'field';
5 };
6 constructor() {
7 this["constructor"](); // calls the field method
8 console.log(this.constructor === C); // should be true
9 }
10}
11const c = new C();
field called
false
r2-p002 · Temporal dead zone after hoisting/reordering in destructuring
1let x;
2({[0]: x} = [99]);
3console.log(x);
4x = 42;
--- orig.js	2026-10-22 14:21:43.883787991 -0400
+++ fixed.js	2026-10-22 14:21:46.497897823 -0400
@@ -1,4 +1,4 @@
 let x;
-({[0]: x} = [99]);
+({0: x} = [99]);
 console.log(x);
 x = 42;
99
r2-p003 · Var hoisting and redeclaration inside loop after use
1for (let i = 0; i < 2; i++) {
2 ({[i]: v} = [{}, {v: 1}]);
3 console.log(v?.v ?? 0);
4 var v = 99;
5}
0
1
r2-p004 · Comment inside brackets detached during bracket removal
1// before
2const o = {[/* keep */'a']: 1};
3// after
4console.log(o.a);
1
r2-p005 · Static block interaction with computed key rewrite
1class Base {
2 static ["staticProp"] = "base";
3}
4class Derived extends Base {
5 static {
6 console.log(this["staticProp"]); // reads rewritten literal
7 }
8 static ["staticProp"] = "derived";
9}
--- orig.js	2026-10-22 14:21:43.884788033 -0400
+++ fixed.js	2026-10-22 14:21:46.554900219 -0400
@@ -1,9 +1,9 @@
 class Base {
-  static ["staticProp"] = "base";
+  static "staticProp" = "base";
 }
 class Derived extends Base {
   static {
     console.log(this["staticProp"]); // reads rewritten literal
   }
-  static ["staticProp"] = "derived";
+  static "staticProp" = "derived";
 }
base
r2-p006 · Exception thrown during evaluation of computed key expression
1try {
2 const obj = {["throw" + "key"]: 1};
3} catch (e) {
4 console.log(e.name, e.message);
5}
r2-p007 · Property order affects enumeration in legacy engines
1const o = {
2 ["2"]: "two",
3 ["1"]: "one"
4};
5let s = '';
6for (const k in o) s += k;
7console.log(s); // expects '21' if computed, '12' if literal due to numeric key ordering
--- orig.js	2026-10-22 14:21:46.365892274 -0400
+++ fixed.js	2026-10-22 14:21:48.453980082 -0400
@@ -1,6 +1,6 @@
 const o = {
-  ["2"]: "two",
-  ["1"]: "one"
+  "2": "two",
+  "1": "one"
 };
 let s = '';
 for (const k in o) s += k;
12
r2-p008 · ASI hazard: leading parenthesis after object literal without semicolon
1let obj = {
2 ["x"]: 1
3}
4(function(){ console.log(obj.x); })()
--- orig.js	2026-10-22 14:21:46.400893745 -0400
+++ fixed.js	2026-10-22 14:21:50.166052132 -0400
@@ -1,4 +1,4 @@
 let obj = {
-  ["x"]: 1
+  "x": 1
 }
 (function(){ console.log(obj.x); })()