diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 9c4ed1128dcb4..704018627b24e 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -138,6 +138,11 @@ namespace ts { const silentNeverType = createIntrinsicType(TypeFlags.Never, "never"); const emptyObjectType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined); + + const emptyTypeLiteralSymbol = createSymbol(SymbolFlags.TypeLiteral | SymbolFlags.Transient, "__type"); + emptyTypeLiteralSymbol.members = createMap(); + const emptyTypeLiteralType = createAnonymousType(emptyTypeLiteralSymbol, emptySymbols, emptyArray, emptyArray, undefined, undefined); + const emptyGenericType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined); emptyGenericType.instantiations = createMap(); @@ -5696,10 +5701,15 @@ namespace ts { const links = getNodeLinks(node); if (!links.resolvedType) { // Deferred resolution of members is handled by resolveObjectTypeMembers - const type = createObjectType(ObjectFlags.Anonymous, node.symbol); - type.aliasSymbol = aliasSymbol; - type.aliasTypeArguments = aliasTypeArguments; - links.resolvedType = type; + if (isEmpty(node.symbol.members) && !aliasSymbol && !aliasTypeArguments) { + links.resolvedType = emptyTypeLiteralType; + } + else { + const type = createObjectType(ObjectFlags.Anonymous, node.symbol); + type.aliasSymbol = aliasSymbol; + type.aliasTypeArguments = aliasTypeArguments; + links.resolvedType = type; + } } return links.resolvedType; } @@ -6036,6 +6046,9 @@ namespace ts { } function isSymbolInScopeOfMappedTypeParameter(symbol: Symbol, mapper: TypeMapper) { + if (!(symbol.declarations && symbol.declarations.length)) { + return false; + } const mappedTypes = mapper.mappedTypes; // Starting with the parent of the symbol's declaration, check if the mapper maps any of // the type parameters introduced by enclosing declarations. We just pick the first