class K { static n = 1; }
K.n = 5; console.log(K.n); // 5 (correct)
K.n += 1; console.log(K.n); // node 6 Perry 5
K["n"] += 1; console.log(K.n); // node 7 Perry 5
const k = "n"; K[k] += 1; console.log(K.n); // node 8 Perry 5
K.n++; console.log(K.n); // node 9 Perry 6 (`++` itself is applied; the three `+=` were lost)
Identical in an ESM .ts module (strict) and a .cts script (sloppy). Compound assignment to a declared static field is silently dropped; plain = (Expr::PutValueSet) and ++ (Expr::PropertyUpdate) on the same field are applied. An undeclared static (class D {}; (D as any).m = 1; (D as any).m += 1 → 2) is correct in both modes, so the dynamic class-property bag is not the problem — the declared static field has its own storage that the = and ++ lanes reach and the Expr::PropertySet lane (o.x += 1, o["x"] += 1, o[k] += 1, and presumably for (K.n of …) / [K.n] = …) does not: the store presumably lands in the class's dynamic-property bag and the next read of K.n comes from the static slot.
Reproduced on fix/propertyset-strict (PR #9519's head, main + two commits that do not touch static fields); the strict lane there is byte-identical to main, so this is pre-existing on main in both modes. Found while building the #9495 fixture (which now uses an undeclared static as its class-ref control instead). Not a strictness or prototype-walk defect — #9459 / #9495 leave it as it was.
Identical in an ESM
.tsmodule (strict) and a.ctsscript (sloppy). Compound assignment to a declaredstaticfield is silently dropped; plain=(Expr::PutValueSet) and++(Expr::PropertyUpdate) on the same field are applied. An undeclared static (class D {}; (D as any).m = 1; (D as any).m += 1→2) is correct in both modes, so the dynamic class-property bag is not the problem — the declared static field has its own storage that the=and++lanes reach and theExpr::PropertySetlane (o.x += 1,o["x"] += 1,o[k] += 1, and presumablyfor (K.n of …)/[K.n] = …) does not: the store presumably lands in the class's dynamic-property bag and the next read ofK.ncomes from the static slot.Reproduced on
fix/propertyset-strict(PR #9519's head,main+ two commits that do not touch static fields); the strict lane there is byte-identical tomain, so this is pre-existing onmainin both modes. Found while building the #9495 fixture (which now uses an undeclared static as its class-ref control instead). Not a strictness or prototype-walk defect — #9459 / #9495 leave it as it was.