elliottv elliottv - 10 days ago 6
TypeScript Question

Typescript compiler forgets adding brackets?

I have an issue with compiling this specific piece of code (this is from an Angular2 project).

public reloadRecords() {
let step = (this.timeInterval.max - this.timeInterval.min) / this.recordsChartSteps;
let data = new Array(this.recordsChartSteps);
let labels = new Array(this.recordsChartSteps);
let doneCount = 0;
let done = new EventEmitter();

done.subscribe(() => {
this.recordsChartData[0].data = data;
this.recordsChartLabels = labels;
});

if (this.timeInterval.min == 0)
this.data.getRecordCount(this.timeInterval.min, this.timeInterval.max).subscribe(count => {
data[data.length - 1] = count;
labels[labels.length - 1] = "Total";

done.emit();
});
else for (let i = 0; i < this.recordsChartSteps; i++) {
let min = this.timeInterval.min + step * i;
let max = min + step - 1;

this.data.getRecordCount(min, max)
.subscribe(count => {
data[i] = count;
labels[i] = "De " + new Date(min).toLocaleTimeString() + " à " + new Date(max).toLocaleTimeString();

if (++doneCount >= this.recordsChartSteps) done.emit();
});
}
}


Using typescript version 2.0.10 (from npm), this is the output I get.

GlobalViewComponent.prototype.reloadRecords = function () {
var _this = this;
var step = (this.timeInterval.max - this.timeInterval.min) / this.recordsChartSteps;
var data = new Array(this.recordsChartSteps);
var labels = new Array(this.recordsChartSteps);
var doneCount = 0;
var done = new core_1.EventEmitter();
done.subscribe(function () {
_this.recordsChartData[0].data = data;
_this.recordsChartLabels = labels;
});
if (this.timeInterval.min == 0)
this.data.getRecordCount(this.timeInterval.min, this.timeInterval.max).subscribe(function (count) {
data[data.length - 1] = count;
labels[labels.length - 1] = "Total";
done.emit();
});
else
var _loop_1 = function(i) {
var min = this_1.timeInterval.min + step * i;
var max = min + step - 1;
this_1.data.getRecordCount(min, max)
.subscribe(function (count) {
data[i] = count;
labels[i] = "De " + new Date(min).toLocaleTimeString() + " à " + new Date(max).toLocaleTimeString();
if (++doneCount >= _this.recordsChartSteps)
done.emit();
});
};
var this_1 = this;
for (var i = 0; i < this.recordsChartSteps; i++) {
_loop_1(i);
}
};


It is valid Javascript code, however it seems that the compiler didn't add the necessary brackets for the contents of the else block.

I understand that this is most likely due to the fact that I didn't add those brackets in my Typescript code as the else statement contains a single block (making the brackets unnecessary, please correct me if I'm wrong).

However, in the Javascript, the else block (a single for loop in Typescript) outputs to multiple statements.

You can even see the indendation, and I think it makes sense that the two instructions following the first one that declares the _loop_1 variable should be contained in this else block aswell.

I obviously could fix the issue by simply adding brackets in my Typescript code (which, I understand, might arguably be better practice).

Was it my mistake to not put those brackets, or is this an issue with the compiler that I should report?

NB: english is not my main language.

Answer

Yes, this looks like a bug, and you should report it. Here a quick simplified reproduction:

var test = false;
if (test) for (let i = 0; i < 10; i++) {
  let x = () => i;
}

Playground link.

That code should definitely do nothing, and it does so if you run it uncompiled in my local Chrome. If you run it through TypeScript though it instead throws 'Uncaught TypeError: _loop_1 is not a function'. Great find!