Skip to content

Change evaluation order of decorator-injected initializers #54267

Closed
@rbuckton

Description

@rbuckton

Per consensus at the May, 2023 TC39 meeting, we need to change the evaluation order of decorator-injected initializers for both accessor and non-accessor fields. More details on the issue can be found here: tc39/proposal-decorators#508.

In summary, given

function minusTwo({ set }) {
  return {
    set(v) { set.call(this, v - 2); },
    init(v) { return v - 2; },
  };
}
function timesFour({ set }) {
  return {
    set(v) { set.call(this, v * 4); },
    init(v) { return v * 4; }
  };
}

class C {
  @minusTwo @timesFour accessor x = 5;
}

const obj = new C();
console.log(obj.x); // (a)

obj.x = 5;
console.log(obj.x); // (b)

Prior to this change, the value at (a) would be 18 (((5) * 4) - 2), while the value at (b) would be 12 (((5) - 2) * 4). This is because the setters wrap and are thus evaluated from the outside-in, while initializers do not wrap and are applied from the inside-out.

After this change, the values at both (a) and (b) would be twelve, as the initializers would be applied outside-in as well.

Metadata

Metadata

Assignees

Labels

BugA bug in TypeScriptES NextNew featurers for ECMAScript (a.k.a. ESNext)Fix AvailableA PR has been opened for this issue

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions