Skip to content

Iteration over Set object with ES2016 is broken, because Set doesn't have length property #16229

@andrewpmontgomery

Description

@andrewpmontgomery

🐞 bug report

Affected Package

Somewhere in the build process, after Typescript (tsc) but before AOT.

Is this a regression?

Don't know.

Description

Code which iterates over a Set is compiled as if Set has a .length property, but it doesn't, the correct property is .size. This silently breaks the logic.

This only happens when using ng build; it doesn't happen with ng serve.

🔬 Minimal Reproduction

Use ng new to create a minimal project.

Add the following to app.component.ts:

export class AppComponent {
  sum = 0;
  constructor() {
    const numSet = new Set([12, 13, 17]);
    for (const num of numSet) {
      this.sum += num;
    }
    console.log(this.sum);
  }
}

In tsconfig.json, make just one change:

"target": "es2016",

Run ng build (not in prod mode).

Here's the compiled main-es2016.js:

var AppComponent = /** @class */ (function () {
  function AppComponent() {
    this.sum = 0;
    var numSet = new Set([12, 13, 17]);
    for (var _i = 0, numSet_1 = numSet; _i < numSet_1.length; _i++) {
      var num = numSet_1[_i];
      this.sum += num;
    }
    console.log(this.sum);
  }
  return AppComponent;
}());

🔥 Exception or Error

this.sum should evaluate to 42; instead it evaluates to zero.
This happens because numSet_1.length is undefined. For the Set object, the compiler should have used the .size property, not .length.

🌍 Your Environment

Angular Version:


Angular CLI: 8.3.19
Node: 10.15.3
OS: win32 x64
Angular: 8.2.14
... animations, common, compiler, compiler-cli, core, forms
... language-service, platform-browser, platform-browser-dynamic
... router

Package                           Version
-----------------------------------------------------------
@angular-devkit/architect         0.803.19
@angular-devkit/build-angular     0.803.19
@angular-devkit/build-optimizer   0.803.19
@angular-devkit/build-webpack     0.803.19
@angular-devkit/core              8.3.19
@angular-devkit/schematics        8.3.19
@angular/cli                      8.3.19
@ngtools/webpack                  8.3.19
@schematics/angular               8.3.19
@schematics/update                0.803.19
rxjs                              6.4.0
typescript                        3.5.3
webpack                           4.39.2

Anything else relevant?
There are plenty of ways to work around this bug, but it's insidious so it really should be fixed.

I can't replicate this in Typescript (with tsc alone), so I assume the problem is in Angular, not in Typescript.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions