@@ -1808,12 +1808,38 @@ namespace ts {
18081808
18091809 /**
18101810 * Writes only the name of the symbol out to the writer. Uses the original source text
1811- * for the name of the symbol if it is available to match how the user inputted the name.
1811+ * for the name of the symbol if it is available to match how the user wrote the name.
18121812 */
18131813 function appendSymbolNameOnly(symbol: Symbol, writer: SymbolWriter): void {
18141814 writer.writeSymbol(getNameOfSymbol(symbol), symbol);
18151815 }
18161816
1817+ /**
1818+ * Writes a property access or element access with the name of the symbol out to the writer.
1819+ * Uses the original source text for the name of the symbol if it is available to match how the user wrote the name,
1820+ * ensuring that any names written with literals use element accesses.
1821+ */
1822+ function appendPropertyOrElementAccessForSymbol(symbol: Symbol, writer: SymbolWriter): void {
1823+ const symbolName = getNameOfSymbol(symbol);
1824+ const firstChar = symbolName.charCodeAt(0);
1825+ const needsElementAccess = !isIdentifierStart(firstChar, languageVersion);
1826+
1827+ if (needsElementAccess) {
1828+ writePunctuation(writer, SyntaxKind.OpenBracketToken);
1829+ if (isSingleOrDoubleQuote(firstChar)) {
1830+ writer.writeStringLiteral(symbolName);
1831+ }
1832+ else {
1833+ writer.writeSymbol(symbolName, symbol);
1834+ }
1835+ writePunctuation(writer, SyntaxKind.CloseBracketToken);
1836+ }
1837+ else {
1838+ writePunctuation(writer, SyntaxKind.DotToken);
1839+ writer.writeSymbol(symbolName, symbol);
1840+ }
1841+ }
1842+
18171843 /**
18181844 * Enclosing declaration is optional when we don't want to get qualified name in the enclosing declaration scope
18191845 * Meaning needs to be specified if the enclosing declaration is given
@@ -1832,10 +1858,12 @@ namespace ts {
18321858 buildTypeParameterDisplayFromSymbol(parentSymbol, writer, enclosingDeclaration);
18331859 }
18341860 }
1835- writePunctuation(writer, SyntaxKind.DotToken);
1861+ appendPropertyOrElementAccessForSymbol(symbol, writer);
1862+ }
1863+ else {
1864+ appendSymbolNameOnly(symbol, writer);
18361865 }
18371866 parentSymbol = symbol;
1838- appendSymbolNameOnly(symbol, writer);
18391867 }
18401868
18411869 // const the writer know we just wrote out a symbol. The declaration emitter writer uses
@@ -2030,10 +2058,10 @@ namespace ts {
20302058 if (symbol) {
20312059 // Always use 'typeof T' for type of class, enum, and module objects
20322060 if (symbol.flags & (SymbolFlags.Class | SymbolFlags.Enum | SymbolFlags.ValueModule)) {
2033- writeTypeofSymbol (type, flags);
2061+ writeTypeOSymbol (type, flags);
20342062 }
20352063 else if (shouldWriteTypeOfFunctionSymbol()) {
2036- writeTypeofSymbol (type, flags);
2064+ writeTypeOSymbol (type, flags);
20372065 }
20382066 else if (contains(symbolStack, symbol)) {
20392067 // If type is an anonymous type literal in a type alias declaration, use type alias name
@@ -2078,7 +2106,7 @@ namespace ts {
20782106 }
20792107 }
20802108
2081- function writeTypeofSymbol (type: ObjectType, typeFormatFlags?: TypeFormatFlags) {
2109+ function writeTypeOSymbol (type: ObjectType, typeFormatFlags?: TypeFormatFlags) {
20822110 writeKeyword(writer, SyntaxKind.TypeOfKeyword);
20832111 writeSpace(writer);
20842112 buildSymbolDisplay(type.symbol, writer, enclosingDeclaration, SymbolFlags.Value, SymbolFormatFlags.None, typeFormatFlags);
0 commit comments