diff --git a/src/compiler/transformers/es2015.ts b/src/compiler/transformers/es2015.ts index 71a2fa0e2e..9dba20be28 100644 --- a/src/compiler/transformers/es2015.ts +++ b/src/compiler/transformers/es2015.ts @@ -3360,10 +3360,13 @@ namespace ts { const classStatements = visitNodes(body.statements, visitor, isStatement, 0, 1); const remainingStatements = visitNodes(body.statements, visitor, isStatement, 1, body.statements.length - 1); const varStatement = cast(firstOrUndefined(classStatements), isVariableStatement); + + // We know there is only one variable declaration here as we verified this in an + // earlier call to isTypeScriptClassWrapper const variable = varStatement.declarationList.declarations[0]; const initializer = skipOuterExpressions(variable.initializer); - // Under certain conditions, the 'ts' transformer may may introduce a class alias, which + // Under certain conditions, the 'ts' transformer may introduce a class alias, which // we see as an assignment, for example: // // (function () { diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts index 4fb21f7ec9..e8a2a2f00c 100644 --- a/src/compiler/transformers/ts.ts +++ b/src/compiler/transformers/ts.ts @@ -573,6 +573,17 @@ namespace ts { addConstructorDecorationStatement(statements, node); if (facts & ClassFacts.UseImmediatelyInvokedFunctionExpression) { + // When we emit a TypeScript class down to ES5, we must wrap it in an IIFE so that the + // 'es2015' transformer can properly nest static initializers and decorators. The result + // looks something like: + // + // var C = function () { + // class C { + // } + // C.static_prop = 1; + // return C; + // }(); + // const closingBraceLocation = createTokenRange(skipTrivia(currentSourceFile.text, node.members.end), SyntaxKind.CloseBraceToken); const localName = getInternalName(node);