Skip to content

Invalid emit for declaring a class that references itself inside of a loop  #31330

Closed

Description

TypeScript Version: Version 3.5.0-dev.20190509

Search Terms:
Class inside loop
Uncaught SyntaxError: Illegal return statement

Code

const classesByRow: Record<string, object> = {};
for (const row of ['1', '2', '3', '4', '5']) {
  class RowClass {
    row = row;
    static factory = () => new RowClass();
  }

  classesByRow[row] = RowClass;
}

console.log(classesByRow)

Expected behavior:
When downleveled to ES5 the compiled code runs and logs something like:

{1: ƒ, 2: ƒ, 3: ƒ, 4: ƒ, 5: ƒ}
  1: class RowClass
  2: class RowClass
  3: class RowClass
  4: class RowClass
  5: class RowClass

Actual behavior:
When downleveled to ES5 the compiled code does not run and throws a syntax error:

Uncaught SyntaxError: Illegal return statement

Playground Link:
https://www.typescriptlang.org/play/index.html#src=const%20classesByRow%3A%20Record%3Cstring%2C%20object%3E%20%3D%20%7B%7D%3B%0Afor%20(const%20row%20of%20%5B'1'%2C%20'2'%2C%20'3'%2C%20'4'%2C%20'5'%5D)%20%7B%0A%20%20class%20RowClass%20%7B%0A%20%20%20%20row%20%3D%20row%3B%0A%20%20%20%20static%20factory%20%3D%20()%20%3D%3E%20new%20RowClass()%3B%0A%20%20%7D%0A%0A%20%20classesByRow%5Brow%5D%20%3D%20RowClass%3B%0A%7D%0A%0Aconsole.log(classesByRow)

Related Issues:
I could not find any.


When downleveling the ES5 in this weird situation the TS compiler produces JS with either a syntax error or incorrect runtime semantics by placing a return statement where it does not belong. This error seems to happen when a class declared inside of a loop has a property that references itself. The error does not happen when the self-referencing property is removed. To test this, remove line 5 from the above example. This issue is reproducable for every kind of loop, not just for ... of loops, it also comes up when using while loops and for loops.

The bug does not happen when targeting ES2015 or above.

I was able to reproduce this on TS 3.3 as well.

Activity

  1. rrdelaney commented on Jun 21, 2019

    @rrdelaney
    Author

    This is still reproducible on TS 3.5.1. Any updates?

  2. locked as resolved and limited conversation to collaborators on Oct 21, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

BugA bug in TypeScriptDomain: JS EmitThe issue relates to the emission of JavaScript

Type

No type

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions