mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-15 04:43:37 -05:00
Use a symbol for untyped modules to distinguish from unknownSymbol
This commit is contained in:
@@ -1099,7 +1099,7 @@ namespace ts {
|
||||
const moduleSymbol = resolveExternalModuleName(node, (<ImportDeclaration>node.parent).moduleSpecifier);
|
||||
|
||||
if (moduleSymbol) {
|
||||
const exportDefaultSymbol = isShorthandAmbientModuleSymbol(moduleSymbol) ?
|
||||
const exportDefaultSymbol = isUntypedOrShorthandAmbientModuleSymbol(moduleSymbol) ?
|
||||
moduleSymbol :
|
||||
moduleSymbol.exports["export="] ?
|
||||
getPropertyOfType(getTypeOfSymbol(moduleSymbol.exports["export="]), "default") :
|
||||
@@ -1175,7 +1175,7 @@ namespace ts {
|
||||
if (targetSymbol) {
|
||||
const name = specifier.propertyName || specifier.name;
|
||||
if (name.text) {
|
||||
if (isShorthandAmbientModuleSymbol(moduleSymbol)) {
|
||||
if (isUntypedOrShorthandAmbientModuleSymbol(moduleSymbol)) {
|
||||
return moduleSymbol;
|
||||
}
|
||||
|
||||
@@ -1427,15 +1427,19 @@ namespace ts {
|
||||
Debug.assert(!!moduleNotFoundError);
|
||||
const diag = Diagnostics.Invalid_module_name_in_augmentation_Module_0_resolves_to_an_untyped_module_at_1_which_cannot_be_augmented;
|
||||
error(errorNode, diag, moduleName, resolvedModule.resolvedFileName);
|
||||
return undefined;
|
||||
}
|
||||
else if (compilerOptions.noImplicitAny && moduleNotFoundError) {
|
||||
error(errorNode,
|
||||
Diagnostics.Could_not_find_a_declaration_file_for_module_0_1_implicitly_has_an_any_type,
|
||||
moduleReference,
|
||||
resolvedModule.resolvedFileName);
|
||||
return undefined;
|
||||
}
|
||||
// Failed imports and untyped modules are both treated in an untyped manner; only difference is whether we give a diagnostic first.
|
||||
return undefined;
|
||||
// Unlike a failed import, an untyped module produces a dummy symbol. This is checked for by `isUntypedOrShorthandAmbientModuleSymbol`.
|
||||
const untypedSymbol = createSymbol(SymbolFlags.ValueModule, `"${moduleName}"`);
|
||||
untypedSymbol.exports = createMap<Symbol>();
|
||||
return untypedSymbol;
|
||||
}
|
||||
|
||||
if (moduleNotFoundError) {
|
||||
@@ -3575,7 +3579,7 @@ namespace ts {
|
||||
function getTypeOfFuncClassEnumModule(symbol: Symbol): Type {
|
||||
const links = getSymbolLinks(symbol);
|
||||
if (!links.type) {
|
||||
if (symbol.flags & SymbolFlags.Module && isShorthandAmbientModuleSymbol(symbol)) {
|
||||
if (symbol.flags & SymbolFlags.Module && isUntypedOrShorthandAmbientModuleSymbol(symbol)) {
|
||||
links.type = anyType;
|
||||
}
|
||||
else {
|
||||
@@ -19610,7 +19614,7 @@ namespace ts {
|
||||
|
||||
function moduleExportsSomeValue(moduleReferenceExpression: Expression): boolean {
|
||||
let moduleSymbol = resolveExternalModuleName(moduleReferenceExpression.parent, moduleReferenceExpression);
|
||||
if (!moduleSymbol || isShorthandAmbientModuleSymbol(moduleSymbol)) {
|
||||
if (!moduleSymbol || isUntypedOrShorthandAmbientModuleSymbol(moduleSymbol)) {
|
||||
// If the module is not found or is shorthand, assume that it may export a value.
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -388,8 +388,8 @@ namespace ts {
|
||||
}
|
||||
|
||||
/** Given a symbol for a module, checks that it is either an untyped import or a shorthand ambient module. */
|
||||
export function isShorthandAmbientModuleSymbol(moduleSymbol: Symbol): boolean {
|
||||
return isShorthandAmbientModule(moduleSymbol.valueDeclaration);
|
||||
export function isUntypedOrShorthandAmbientModuleSymbol(moduleSymbol: Symbol): boolean {
|
||||
return !moduleSymbol.valueDeclaration || isShorthandAmbientModule(moduleSymbol.valueDeclaration);
|
||||
}
|
||||
|
||||
function isShorthandAmbientModule(node: Node): boolean {
|
||||
|
||||
14
tests/baselines/reference/extendsUntypedModule.errors.txt
Normal file
14
tests/baselines/reference/extendsUntypedModule.errors.txt
Normal file
@@ -0,0 +1,14 @@
|
||||
/a.ts(2,17): error TS2507: Type 'any' is not a constructor function type.
|
||||
|
||||
|
||||
==== /a.ts (1 errors) ====
|
||||
import Foo from "foo";
|
||||
class A extends Foo { }
|
||||
~~~
|
||||
!!! error TS2507: Type 'any' is not a constructor function type.
|
||||
|
||||
==== /node_modules/foo/index.js (0 errors) ====
|
||||
// Test that extending an untyped module is an error, unlike extending unknownSymbol.
|
||||
|
||||
This file is not read.
|
||||
|
||||
27
tests/baselines/reference/extendsUntypedModule.js
Normal file
27
tests/baselines/reference/extendsUntypedModule.js
Normal file
@@ -0,0 +1,27 @@
|
||||
//// [tests/cases/compiler/extendsUntypedModule.ts] ////
|
||||
|
||||
//// [index.js]
|
||||
// Test that extending an untyped module is an error, unlike extending unknownSymbol.
|
||||
|
||||
This file is not read.
|
||||
|
||||
//// [a.ts]
|
||||
import Foo from "foo";
|
||||
class A extends Foo { }
|
||||
|
||||
|
||||
//// [a.js]
|
||||
"use strict";
|
||||
var __extends = (this && this.__extends) || function (d, b) {
|
||||
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
|
||||
function __() { this.constructor = d; }
|
||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||
};
|
||||
var foo_1 = require("foo");
|
||||
var A = (function (_super) {
|
||||
__extends(A, _super);
|
||||
function A() {
|
||||
return _super.apply(this, arguments) || this;
|
||||
}
|
||||
return A;
|
||||
}(foo_1["default"]));
|
||||
9
tests/cases/compiler/extendsUntypedModule.ts
Normal file
9
tests/cases/compiler/extendsUntypedModule.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
// Test that extending an untyped module is an error, unlike extending unknownSymbol.
|
||||
// @noImplicitReferences: true
|
||||
|
||||
// @Filename: /node_modules/foo/index.js
|
||||
This file is not read.
|
||||
|
||||
// @Filename: /a.ts
|
||||
import Foo from "foo";
|
||||
class A extends Foo { }
|
||||
@@ -13,7 +13,7 @@ verify.numberOfErrorsInCurrentFile(0);
|
||||
|
||||
goTo.marker("fooModule");
|
||||
verify.goToDefinitionIs([]);
|
||||
verify.quickInfoIs("");
|
||||
verify.quickInfoIs('module "foo"');
|
||||
verify.referencesAre([])
|
||||
|
||||
goTo.marker("foo");
|
||||
|
||||
Reference in New Issue
Block a user