@@ -594,12 +594,11 @@ namespace ts {
594594 emitLines ( node . statements ) ;
595595 }
596596
597- // Return a temp variable name to be used in `export default` statements.
597+ // Return a temp variable name to be used in `export default`/`export class ... extends` statements.
598598 // The temp name will be of the form _default_counter.
599599 // Note that export default is only allowed at most once in a module, so we
600600 // do not need to keep track of created temp names.
601- function getExportDefaultTempVariableName ( ) : string {
602- const baseName = "_default" ;
601+ function getExportTempVariableName ( baseName : string ) : string {
603602 if ( ! currentIdentifiers . has ( baseName ) ) {
604603 return baseName ;
605604 }
@@ -613,24 +612,31 @@ namespace ts {
613612 }
614613 }
615614
615+ function emitTempVariableDeclaration ( expr : Expression , baseName : string , diagnostic : SymbolAccessibilityDiagnostic ) : string {
616+ const tempVarName = getExportTempVariableName ( baseName ) ;
617+ if ( ! noDeclare ) {
618+ write ( "declare " ) ;
619+ }
620+ write ( "var " ) ;
621+ write ( tempVarName ) ;
622+ write ( ": " ) ;
623+ writer . getSymbolAccessibilityDiagnostic = ( ) => diagnostic ;
624+ resolver . writeTypeOfExpression ( expr , enclosingDeclaration , TypeFormatFlags . UseTypeOfFunction | TypeFormatFlags . UseTypeAliasValue , writer ) ;
625+ write ( ";" ) ;
626+ writeLine ( ) ;
627+ return tempVarName ;
628+ }
629+
616630 function emitExportAssignment ( node : ExportAssignment ) {
617631 if ( node . expression . kind === SyntaxKind . Identifier ) {
618632 write ( node . isExportEquals ? "export = " : "export default " ) ;
619633 writeTextOfNode ( currentText , node . expression ) ;
620634 }
621635 else {
622- // Expression
623- const tempVarName = getExportDefaultTempVariableName ( ) ;
624- if ( ! noDeclare ) {
625- write ( "declare " ) ;
626- }
627- write ( "var " ) ;
628- write ( tempVarName ) ;
629- write ( ": " ) ;
630- writer . getSymbolAccessibilityDiagnostic = getDefaultExportAccessibilityDiagnostic ;
631- resolver . writeTypeOfExpression ( node . expression , enclosingDeclaration , TypeFormatFlags . UseTypeOfFunction | TypeFormatFlags . UseTypeAliasValue , writer ) ;
632- write ( ";" ) ;
633- writeLine ( ) ;
636+ const tempVarName = emitTempVariableDeclaration ( node . expression , "_default" , {
637+ diagnosticMessage : Diagnostics . Default_export_of_the_module_has_or_is_using_private_name_0 ,
638+ errorNode : node
639+ } ) ;
634640 write ( node . isExportEquals ? "export = " : "export default " ) ;
635641 write ( tempVarName ) ;
636642 }
@@ -644,13 +650,6 @@ namespace ts {
644650 // write each of these declarations asynchronously
645651 writeAsynchronousModuleElements ( nodes ) ;
646652 }
647-
648- function getDefaultExportAccessibilityDiagnostic ( ) : SymbolAccessibilityDiagnostic {
649- return {
650- diagnosticMessage : Diagnostics . Default_export_of_the_module_has_or_is_using_private_name_0 ,
651- errorNode : node
652- } ;
653- }
654653 }
655654
656655 function isModuleElementVisible ( node : Declaration ) {
@@ -1113,7 +1112,11 @@ namespace ts {
11131112 else {
11141113 writer . getSymbolAccessibilityDiagnostic = getHeritageClauseVisibilityError ;
11151114 errorNameNode = className ;
1116- resolver . writeBaseConstructorTypeOfClass ( < ClassLikeDeclaration > enclosingDeclaration , enclosingDeclaration , TypeFormatFlags . UseTypeOfFunction | TypeFormatFlags . UseTypeAliasValue , writer ) ;
1115+ resolver . writeBaseConstructorTypeOfClass (
1116+ enclosingDeclaration as ClassLikeDeclaration ,
1117+ enclosingDeclaration ,
1118+ TypeFormatFlags . UseTypeOfFunction | TypeFormatFlags . UseTypeAliasValue ,
1119+ writer ) ;
11171120 errorNameNode = undefined ;
11181121 }
11191122
@@ -1151,21 +1154,39 @@ namespace ts {
11511154 }
11521155 }
11531156
1157+ const prevEnclosingDeclaration = enclosingDeclaration ;
1158+ enclosingDeclaration = node ;
1159+ const baseTypeNode = getClassExtendsHeritageClauseElement ( node ) ;
1160+ let tempVarName : string ;
1161+ if ( isNonNullExpression ( baseTypeNode ) ) {
1162+ tempVarName = emitTempVariableDeclaration ( baseTypeNode . expression , `_${ node . name . text } _intersection_base` , {
1163+ diagnosticMessage : Diagnostics . extends_clause_of_exported_class_0_has_or_is_using_private_name_1 ,
1164+ errorNode : baseTypeNode ,
1165+ typeName : node . name
1166+ } ) ;
1167+ }
1168+
11541169 emitJsDocComments ( node ) ;
11551170 emitModuleElementDeclarationFlags ( node ) ;
11561171 if ( hasModifier ( node , ModifierFlags . Abstract ) ) {
11571172 write ( "abstract " ) ;
11581173 }
1159-
11601174 write ( "class " ) ;
11611175 writeTextOfNode ( currentText , node . name ) ;
1162- const prevEnclosingDeclaration = enclosingDeclaration ;
1163- enclosingDeclaration = node ;
11641176 emitTypeParameters ( node . typeParameters ) ;
1165- const baseTypeNode = getClassExtendsHeritageClauseElement ( node ) ;
11661177 if ( baseTypeNode ) {
1167- node . name ;
1168- emitHeritageClause ( node . name , [ baseTypeNode ] , /*isImplementsList*/ false ) ;
1178+ if ( isNonNullExpression ( baseTypeNode ) ) {
1179+ write ( " extends " ) ;
1180+ write ( tempVarName ) ;
1181+ if ( baseTypeNode . typeArguments ) {
1182+ write ( "<" ) ;
1183+ emitCommaList ( baseTypeNode . typeArguments , emitType ) ;
1184+ write ( ">" ) ;
1185+ }
1186+ }
1187+ else {
1188+ emitHeritageClause ( node . name , [ baseTypeNode ] , /*isImplementsList*/ false ) ;
1189+ }
11691190 }
11701191 emitHeritageClause ( node . name , getClassImplementsHeritageClauseElements ( node ) , /*isImplementsList*/ true ) ;
11711192 write ( " {" ) ;
@@ -1201,6 +1222,10 @@ namespace ts {
12011222 enclosingDeclaration = prevEnclosingDeclaration ;
12021223 }
12031224
1225+ function isNonNullExpression ( node : ExpressionWithTypeArguments ) {
1226+ return node && ! isEntityNameExpression ( node . expression ) && node . expression . kind !== SyntaxKind . NullKeyword ;
1227+ }
1228+
12041229 function emitPropertyDeclaration ( node : Declaration ) {
12051230 if ( hasDynamicName ( node ) ) {
12061231 return ;
0 commit comments