diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 4493682ed51..7d7ed2afb52 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -3667,12 +3667,23 @@ namespace ts { return links.declaredType; } + function createEnumType(symbol: Symbol): Type { + const type = createType(TypeFlags.Enum); + type.symbol = symbol; + return type; + } + + function getEnumMemberType(symbol: Symbol): Type { + const links = getSymbolLinks(getParentOfSymbol(symbol)); + const map = links.enumMemberTypes || (links.enumMemberTypes = {}); + const value = "" + getEnumMemberValue(symbol.valueDeclaration); + return map[value] || (map[value] = createEnumType(symbol)); + } + function getDeclaredTypeOfEnum(symbol: Symbol): Type { const links = getSymbolLinks(symbol); if (!links.declaredType) { - const type = createType(TypeFlags.Enum); - type.symbol = symbol; - links.declaredType = type; + links.declaredType = symbol.flags & SymbolFlags.EnumMember ? getEnumMemberType(symbol) : createEnumType(symbol); } return links.declaredType; } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 486f1e82a97..3dedd5da1e3 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -2136,6 +2136,7 @@ namespace ts { isDeclarationWithCollidingName?: boolean; // True if symbol is block scoped redeclaration bindingElement?: BindingElement; // Binding element associated with property symbol exportsSomeValue?: boolean; // True if module exports some value (not just types) + enumMemberTypes?: Map; // Enum member types indexed by enum value } /* @internal */