Skip to content

Side effect bugs with logical assignment #39172

Closed
@evanw

Description

@evanw

TypeScript Version: Nightly

Search Terms: logical assignment side effect

Code

This code is from lgcl-nullish-assignment-operator-lhs-before-rhs.js, a test262 conformance test.

var assert = {
  sameValue(a, b, error) {
    if (a !== b) throw new Error(`${error}: ${a} !== ${b}`)
  }
}

var count = 0;
var obj = {};
function incr() {
  return ++count;
}

assert.sameValue(obj[incr()] ??= incr(), 2, "obj[incr()] ??= incr()");
assert.sameValue(obj[1], 2, "obj[1]");
assert.sameValue(count, 2, "count");

Expected behavior: This code should exit cleanly

Actual behavior: This code crashes with Uncaught Error: obj[incr()] ??= incr(): 3 !== 2

The problem is that TypeScript evaluates the property key in the property access twice instead of capturing the value and only evaluating it once.

TypeScript generates this (incorrect):

(_a = (_b = obj)[incr()]) !== null && _a !== void 0 ? _a : (_b[incr()] = incr());

Babel generates this (correct):

(_a = obj[_b = incr()]) !== null && _a !== void 0 ? _a : obj[_b] = incr();

Playground Link: link

Related Issues: #37255 #37727

Metadata

Metadata

Assignees

No one assigned

    Labels

    BugA bug in TypeScript

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions