diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index c751c37c6d5..787604b3d41 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -4426,6 +4426,22 @@ namespace ts { return location.kind === SyntaxKind.SourceFile || isAmbientModule(location); } + function getNameOfSymbolFromNameType(symbol: Symbol, context?: NodeBuilderContext) { + const nameType = symbol.nameType; + if (nameType) { + if (nameType.flags & TypeFlags.StringOrNumberLiteral) { + const name = "" + (nameType).value; + if (!isIdentifierText(name, compilerOptions.target) && !isNumericLiteralName(name)) { + return `"${escapeString(name, CharacterCodes.doubleQuote)}"`; + } + return name; + } + if (nameType.flags & TypeFlags.UniqueESSymbol) { + return `[${getNameOfSymbolAsWritten((nameType).symbol, context)}]`; + } + } + } + /** * Gets a human-readable name for a symbol. * Should *not* be used for the right-hand side of a `.` -- use `symbolName(symbol)` for that instead. @@ -4450,6 +4466,13 @@ namespace ts { if (isCallExpression(declaration) && isBindableObjectDefinePropertyCall(declaration)) { return symbolName(symbol); } + if (isComputedPropertyName(name) && !(getCheckFlags(symbol) & CheckFlags.Late) && symbol.nameType && symbol.nameType.flags & TypeFlags.StringOrNumberLiteral) { + // Computed property name isn't late bound, but has a well-known name type - use name type to generate a symbol name + const result = getNameOfSymbolFromNameType(symbol, context); + if (result !== undefined) { + return result; + } + } return declarationNameToString(name); } if (declaration.parent && declaration.parent.kind === SyntaxKind.VariableDeclaration) { @@ -4465,16 +4488,8 @@ namespace ts { return declaration.kind === SyntaxKind.ClassExpression ? "(Anonymous class)" : "(Anonymous function)"; } } - const nameType = symbol.nameType; - if (nameType) { - if (nameType.flags & TypeFlags.StringLiteral && !isIdentifierText((nameType).value, compilerOptions.target)) { - return `"${escapeString((nameType).value, CharacterCodes.doubleQuote)}"`; - } - if (nameType && nameType.flags & TypeFlags.UniqueESSymbol) { - return `[${getNameOfSymbolAsWritten((nameType).symbol, context)}]`; - } - } - return symbolName(symbol); + const name = getNameOfSymbolFromNameType(symbol, context); + return name !== undefined ? name : symbolName(symbol); } function isDeclarationVisible(node: Node): boolean { diff --git a/tests/baselines/reference/declarationEmitComputedNameConstEnumAlias.js b/tests/baselines/reference/declarationEmitComputedNameConstEnumAlias.js new file mode 100644 index 00000000000..461eb21087e --- /dev/null +++ b/tests/baselines/reference/declarationEmitComputedNameConstEnumAlias.js @@ -0,0 +1,44 @@ +//// [tests/cases/compiler/declarationEmitComputedNameConstEnumAlias.ts] //// + +//// [EnumExample.ts] +enum EnumExample { + TEST = 'TEST', +} + +export default EnumExample; + +//// [index.ts] +import EnumExample from './EnumExample'; + +export default { + [EnumExample.TEST]: {}, +}; + +//// [EnumExample.js] +"use strict"; +exports.__esModule = true; +var EnumExample; +(function (EnumExample) { + EnumExample["TEST"] = "TEST"; +})(EnumExample || (EnumExample = {})); +exports["default"] = EnumExample; +//// [index.js] +"use strict"; +exports.__esModule = true; +var _a; +var EnumExample_1 = require("./EnumExample"); +exports["default"] = (_a = {}, + _a[EnumExample_1["default"].TEST] = {}, + _a); + + +//// [EnumExample.d.ts] +declare enum EnumExample { + TEST = "TEST" +} +export default EnumExample; +//// [index.d.ts] +declare const _default: { + TEST: {}; +}; +export default _default; diff --git a/tests/baselines/reference/declarationEmitComputedNameConstEnumAlias.symbols b/tests/baselines/reference/declarationEmitComputedNameConstEnumAlias.symbols new file mode 100644 index 00000000000..fa5fc6aa482 --- /dev/null +++ b/tests/baselines/reference/declarationEmitComputedNameConstEnumAlias.symbols @@ -0,0 +1,23 @@ +=== tests/cases/compiler/EnumExample.ts === +enum EnumExample { +>EnumExample : Symbol(EnumExample, Decl(EnumExample.ts, 0, 0)) + + TEST = 'TEST', +>TEST : Symbol(EnumExample.TEST, Decl(EnumExample.ts, 0, 18)) +} + +export default EnumExample; +>EnumExample : Symbol(EnumExample, Decl(EnumExample.ts, 0, 0)) + +=== tests/cases/compiler/index.ts === +import EnumExample from './EnumExample'; +>EnumExample : Symbol(EnumExample, Decl(index.ts, 0, 6)) + +export default { + [EnumExample.TEST]: {}, +>[EnumExample.TEST] : Symbol([EnumExample.TEST], Decl(index.ts, 2, 16)) +>EnumExample.TEST : Symbol(EnumExample.TEST, Decl(EnumExample.ts, 0, 18)) +>EnumExample : Symbol(EnumExample, Decl(index.ts, 0, 6)) +>TEST : Symbol(EnumExample.TEST, Decl(EnumExample.ts, 0, 18)) + +}; diff --git a/tests/baselines/reference/declarationEmitComputedNameConstEnumAlias.types b/tests/baselines/reference/declarationEmitComputedNameConstEnumAlias.types new file mode 100644 index 00000000000..97be9ac5a1b --- /dev/null +++ b/tests/baselines/reference/declarationEmitComputedNameConstEnumAlias.types @@ -0,0 +1,27 @@ +=== tests/cases/compiler/EnumExample.ts === +enum EnumExample { +>EnumExample : EnumExample + + TEST = 'TEST', +>TEST : EnumExample.TEST +>'TEST' : "TEST" +} + +export default EnumExample; +>EnumExample : EnumExample + +=== tests/cases/compiler/index.ts === +import EnumExample from './EnumExample'; +>EnumExample : typeof EnumExample + +export default { +>{ [EnumExample.TEST]: {},} : { [EnumExample.TEST]: {}; } + + [EnumExample.TEST]: {}, +>[EnumExample.TEST] : {} +>EnumExample.TEST : EnumExample +>EnumExample : typeof EnumExample +>TEST : EnumExample +>{} : {} + +}; diff --git a/tests/baselines/reference/parserComputedPropertyName35.types b/tests/baselines/reference/parserComputedPropertyName35.types index bfaaca1f942..6c4a9c785e5 100644 --- a/tests/baselines/reference/parserComputedPropertyName35.types +++ b/tests/baselines/reference/parserComputedPropertyName35.types @@ -1,6 +1,6 @@ === tests/cases/conformance/parser/ecmascript6/ComputedPropertyNames/parserComputedPropertyName35.ts === var x = { ->x : { [0, 1]: {}; } +>x : { 1: {}; } >{ [0, 1]: { }} : { [0, 1]: {}; } [0, 1]: { } diff --git a/tests/cases/compiler/declarationEmitComputedNameConstEnumAlias.ts b/tests/cases/compiler/declarationEmitComputedNameConstEnumAlias.ts new file mode 100644 index 00000000000..951ec0b0a9d --- /dev/null +++ b/tests/cases/compiler/declarationEmitComputedNameConstEnumAlias.ts @@ -0,0 +1,14 @@ +// @declaration: true +// @filename: EnumExample.ts +enum EnumExample { + TEST = 'TEST', +} + +export default EnumExample; + +// @filename: index.ts +import EnumExample from './EnumExample'; + +export default { + [EnumExample.TEST]: {}, +}; \ No newline at end of file