From 63319d1ed99fd7f2a4c5deb7f7599310c757a161 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sat, 29 Apr 2017 15:27:25 -0700 Subject: [PATCH] Treat enums with a single literal member as literal enums --- src/compiler/checker.ts | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 689d3e44a7c..ebc5c0677b3 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -3047,9 +3047,14 @@ namespace ts { writeTypeReference(type, nextFlags); } else if (type.flags & TypeFlags.EnumLiteral && !(type.flags & TypeFlags.Union)) { - buildSymbolDisplay(getParentOfSymbol(type.symbol), writer, enclosingDeclaration, SymbolFlags.Type, SymbolFormatFlags.None, nextFlags); - writePunctuation(writer, SyntaxKind.DotToken); - appendSymbolNameOnly(type.symbol, writer); + const parent = getParentOfSymbol(type.symbol); + buildSymbolDisplay(parent, writer, enclosingDeclaration, SymbolFlags.Type, SymbolFormatFlags.None, nextFlags); + // In a literal enum type with a single member E { A }, E and E.A denote the + // same type. We always display this type simply as E. + if (getDeclaredTypeOfSymbol(parent).flags & TypeFlags.Union) { + writePunctuation(writer, SyntaxKind.DotToken); + appendSymbolNameOnly(type.symbol, writer); + } } else if (getObjectFlags(type) & ObjectFlags.ClassOrInterface || type.flags & (TypeFlags.EnumLike | TypeFlags.TypeParameter)) { // The specified symbol flags need to be reinterpreted as type flags @@ -4952,23 +4957,19 @@ namespace ts { if (declaration.kind === SyntaxKind.EnumDeclaration) { for (const member of (declaration).members) { const memberType = getLiteralType(getEnumMemberValue(member), enumCount, getSymbolOfNode(member)); + getSymbolLinks(getSymbolOfNode(member)).declaredType = memberType; if (!contains(memberTypeList, memberType)) { memberTypeList.push(memberType); } } } } - if (memberTypeList.length > 1) { - for (const declaration of symbol.declarations) { - if (declaration.kind === SyntaxKind.EnumDeclaration) { - for (const member of (declaration).members) { - getSymbolLinks(getSymbolOfNode(member)).declaredType = getLiteralType(getEnumMemberValue(member), enumCount, getSymbolOfNode(member)); - } - } - } + if (memberTypeList.length) { const enumType = getUnionType(memberTypeList, /*subtypeReduction*/ false, symbol, /*aliasTypeArguments*/ undefined); - enumType.flags |= TypeFlags.EnumLiteral; - enumType.symbol = symbol; + if (enumType.flags & TypeFlags.Union) { + enumType.flags |= TypeFlags.EnumLiteral; + enumType.symbol = symbol; + } return links.declaredType = enumType; } }