@@ -197,6 +197,8 @@ namespace ts {
197197 const evolvingArrayTypes: EvolvingArrayType[] = [];
198198
199199 const unknownSymbol = createSymbol(SymbolFlags.Property, "unknown");
200+ const untypedModuleSymbol = createSymbol(SymbolFlags.ValueModule, "<untyped>");
201+ untypedModuleSymbol.exports = createMap<Symbol>();
200202 const resolvingSymbol = createSymbol(0, "__resolving__");
201203
202204 const anyType = createIntrinsicType(TypeFlags.Any, "any");
@@ -1227,7 +1229,7 @@ namespace ts {
12271229
12281230 if (moduleSymbol) {
12291231 let exportDefaultSymbol: Symbol;
1230- if (isShorthandAmbientModuleSymbol (moduleSymbol)) {
1232+ if (isUntypedOrShorthandAmbientModuleSymbol (moduleSymbol)) {
12311233 exportDefaultSymbol = moduleSymbol;
12321234 }
12331235 else {
@@ -1307,7 +1309,7 @@ namespace ts {
13071309 if (targetSymbol) {
13081310 const name = specifier.propertyName || specifier.name;
13091311 if (name.text) {
1310- if (isShorthandAmbientModuleSymbol (moduleSymbol)) {
1312+ if (isUntypedOrShorthandAmbientModuleSymbol (moduleSymbol)) {
13111313 return moduleSymbol;
13121314 }
13131315
@@ -1560,15 +1562,19 @@ namespace ts {
15601562 if (isForAugmentation) {
15611563 const diag = Diagnostics.Invalid_module_name_in_augmentation_Module_0_resolves_to_an_untyped_module_at_1_which_cannot_be_augmented;
15621564 error(errorNode, diag, moduleReference, resolvedModule.resolvedFileName);
1565+ return undefined;
15631566 }
15641567 else if (compilerOptions.noImplicitAny && moduleNotFoundError) {
15651568 error(errorNode,
15661569 Diagnostics.Could_not_find_a_declaration_file_for_module_0_1_implicitly_has_an_any_type,
15671570 moduleReference,
15681571 resolvedModule.resolvedFileName);
1572+ return undefined;
15691573 }
1570- // Failed imports and untyped modules are both treated in an untyped manner; only difference is whether we give a diagnostic first.
1571- return undefined;
1574+ // Unlike a failed import, an untyped module produces a dummy symbol.
1575+ // This is checked for by `isUntypedOrShorthandAmbientModuleSymbol`.
1576+ // This must be different than `unknownSymbol` because `getBaseConstructorTypeOfClass` won't fail for `unknownSymbol`.
1577+ return untypedModuleSymbol;
15721578 }
15731579
15741580 if (moduleNotFoundError) {
@@ -3753,7 +3759,7 @@ namespace ts {
37533759 function getTypeOfFuncClassEnumModule(symbol: Symbol): Type {
37543760 const links = getSymbolLinks(symbol);
37553761 if (!links.type) {
3756- if (symbol.flags & SymbolFlags.Module && isShorthandAmbientModuleSymbol (symbol)) {
3762+ if (symbol.flags & SymbolFlags.Module && isUntypedOrShorthandAmbientModuleSymbol (symbol)) {
37573763 links.type = anyType;
37583764 }
37593765 else {
@@ -11578,7 +11584,7 @@ namespace ts {
1157811584 if (isBindingPattern(declaration.parent)) {
1157911585 const parentDeclaration = declaration.parent.parent;
1158011586 const name = declaration.propertyName || declaration.name;
11581- if (isVariableLike( parentDeclaration) &&
11587+ if (parentDeclaration.kind !== SyntaxKind.BindingElement &&
1158211588 parentDeclaration.type &&
1158311589 !isBindingPattern(name)) {
1158411590 const text = getTextOfPropertyName(name);
@@ -21138,7 +21144,15 @@ namespace ts {
2113821144 }
2113921145
2114021146 if (isPartOfTypeNode(node)) {
21141- return getTypeFromTypeNode(<TypeNode>node);
21147+ let typeFromTypeNode = getTypeFromTypeNode(<TypeNode>node);
21148+
21149+ if (typeFromTypeNode && isExpressionWithTypeArgumentsInClassImplementsClause(node)) {
21150+ const containingClass = getContainingClass(node);
21151+ const classType = getTypeOfNode(containingClass) as InterfaceType;
21152+ typeFromTypeNode = getTypeWithThisArgument(typeFromTypeNode, classType.thisType);
21153+ }
21154+
21155+ return typeFromTypeNode;
2114221156 }
2114321157
2114421158 if (isPartOfExpression(node)) {
@@ -21148,7 +21162,10 @@ namespace ts {
2114821162 if (isExpressionWithTypeArgumentsInClassExtendsClause(node)) {
2114921163 // A SyntaxKind.ExpressionWithTypeArguments is considered a type node, except when it occurs in the
2115021164 // extends clause of a class. We handle that case here.
21151- return getBaseTypes(<InterfaceType>getDeclaredTypeOfSymbol(getSymbolOfNode(node.parent.parent)))[0];
21165+ const classNode = getContainingClass(node);
21166+ const classType = getDeclaredTypeOfSymbol(getSymbolOfNode(classNode)) as InterfaceType;
21167+ const baseType = getBaseTypes(classType)[0];
21168+ return baseType && getTypeWithThisArgument(baseType, classType.thisType);
2115221169 }
2115321170
2115421171 if (isTypeDeclaration(node)) {
@@ -21316,7 +21333,7 @@ namespace ts {
2131621333
2131721334 function moduleExportsSomeValue(moduleReferenceExpression: Expression): boolean {
2131821335 let moduleSymbol = resolveExternalModuleName(moduleReferenceExpression.parent, moduleReferenceExpression);
21319- if (!moduleSymbol || isShorthandAmbientModuleSymbol (moduleSymbol)) {
21336+ if (!moduleSymbol || isUntypedOrShorthandAmbientModuleSymbol (moduleSymbol)) {
2132021337 // If the module is not found or is shorthand, assume that it may export a value.
2132121338 return true;
2132221339 }
0 commit comments