diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 3d13ba63fa..867eebb04a 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -922,6 +922,7 @@ namespace ts { if (!errorLocation || !checkAndReportErrorForMissingPrefix(errorLocation, name, nameArg) && !checkAndReportErrorForExtendingInterface(errorLocation) && + !checkAndReportErrorForUsingTypeAsNamespace(errorLocation, name, meaning) && !checkAndReportErrorForUsingTypeAsValue(errorLocation, name, meaning)) { error(errorLocation, nameNotFoundMessage, typeof nameArg === "string" ? nameArg : declarationNameToString(nameArg)); } @@ -1032,6 +1033,18 @@ namespace ts { } } + function checkAndReportErrorForUsingTypeAsNamespace(errorLocation: Node, name: string, meaning: SymbolFlags): boolean { + if (meaning === SymbolFlags.Namespace) { + const symbol = resolveSymbol(resolveName(errorLocation, name, SymbolFlags.Type & ~SymbolFlags.Value, /*nameNotFoundMessage*/undefined, /*nameArg*/ undefined)); + if (symbol) { + error(errorLocation, Diagnostics._0_only_refers_to_a_type_but_is_being_used_as_a_namespace_here, name); + return true; + } + } + + return false; + } + function checkAndReportErrorForUsingTypeAsValue(errorLocation: Node, name: string, meaning: SymbolFlags): boolean { if (meaning & (SymbolFlags.Value & ~SymbolFlags.NamespaceModule)) { const symbol = resolveSymbol(resolveName(errorLocation, name, SymbolFlags.Type & ~SymbolFlags.Value, /*nameNotFoundMessage*/undefined, /*nameArg*/ undefined)); diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index b823b1ed6b..5a22d7d40d 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -1995,6 +1995,10 @@ "category": "Error", "code": 2701 }, + "'{0}' only refers to a type, but is being used as a namespace here.": { + "category": "Error", + "code": 2702 + }, "Import declaration '{0}' is using private name '{1}'.": { "category": "Error", diff --git a/tests/baselines/reference/invalidImportAliasIdentifiers.errors.txt b/tests/baselines/reference/invalidImportAliasIdentifiers.errors.txt index bf5cf5c0f1..c69cc85ad9 100644 --- a/tests/baselines/reference/invalidImportAliasIdentifiers.errors.txt +++ b/tests/baselines/reference/invalidImportAliasIdentifiers.errors.txt @@ -1,6 +1,6 @@ tests/cases/conformance/internalModules/importDeclarations/invalidImportAliasIdentifiers.ts(5,12): error TS2503: Cannot find namespace 'V'. tests/cases/conformance/internalModules/importDeclarations/invalidImportAliasIdentifiers.ts(11,12): error TS2503: Cannot find namespace 'C'. -tests/cases/conformance/internalModules/importDeclarations/invalidImportAliasIdentifiers.ts(23,12): error TS2693: 'I' only refers to a type, but is being used as a value here. +tests/cases/conformance/internalModules/importDeclarations/invalidImportAliasIdentifiers.ts(23,12): error TS2702: 'I' only refers to a type, but is being used as a namespace here. ==== tests/cases/conformance/internalModules/importDeclarations/invalidImportAliasIdentifiers.ts (3 errors) ==== @@ -32,5 +32,5 @@ tests/cases/conformance/internalModules/importDeclarations/invalidImportAliasIde import i = I; ~ -!!! error TS2693: 'I' only refers to a type, but is being used as a value here. +!!! error TS2702: 'I' only refers to a type, but is being used as a namespace here. \ No newline at end of file diff --git a/tests/baselines/reference/invalidUseOfTypeAsNamespace.errors.txt b/tests/baselines/reference/invalidUseOfTypeAsNamespace.errors.txt new file mode 100644 index 0000000000..0353d46d63 --- /dev/null +++ b/tests/baselines/reference/invalidUseOfTypeAsNamespace.errors.txt @@ -0,0 +1,11 @@ +tests/cases/compiler/invalidUseOfTypeAsNamespace.ts(4,16): error TS2702: 'OhNo' only refers to a type, but is being used as a namespace here. + + +==== tests/cases/compiler/invalidUseOfTypeAsNamespace.ts (1 errors) ==== + interface OhNo { + } + + declare let y: OhNo.hello; + ~~~~ +!!! error TS2702: 'OhNo' only refers to a type, but is being used as a namespace here. + \ No newline at end of file diff --git a/tests/baselines/reference/invalidUseOfTypeAsNamespace.js b/tests/baselines/reference/invalidUseOfTypeAsNamespace.js new file mode 100644 index 0000000000..3b598fdea9 --- /dev/null +++ b/tests/baselines/reference/invalidUseOfTypeAsNamespace.js @@ -0,0 +1,8 @@ +//// [invalidUseOfTypeAsNamespace.ts] +interface OhNo { +} + +declare let y: OhNo.hello; + + +//// [invalidUseOfTypeAsNamespace.js] diff --git a/tests/baselines/reference/strictModeReservedWordInClassDeclaration.errors.txt b/tests/baselines/reference/strictModeReservedWordInClassDeclaration.errors.txt index 0dff64c9a3..fafffb563e 100644 --- a/tests/baselines/reference/strictModeReservedWordInClassDeclaration.errors.txt +++ b/tests/baselines/reference/strictModeReservedWordInClassDeclaration.errors.txt @@ -16,9 +16,9 @@ tests/cases/compiler/strictModeReservedWordInClassDeclaration.ts(21,9): error TS tests/cases/compiler/strictModeReservedWordInClassDeclaration.ts(21,17): error TS1213: Identifier expected. 'private' is a reserved word in strict mode. Class definitions are automatically in strict mode. tests/cases/compiler/strictModeReservedWordInClassDeclaration.ts(23,20): error TS1213: Identifier expected. 'public' is a reserved word in strict mode. Class definitions are automatically in strict mode. tests/cases/compiler/strictModeReservedWordInClassDeclaration.ts(25,20): error TS1213: Identifier expected. 'public' is a reserved word in strict mode. Class definitions are automatically in strict mode. -tests/cases/compiler/strictModeReservedWordInClassDeclaration.ts(25,20): error TS2693: 'public' only refers to a type, but is being used as a value here. +tests/cases/compiler/strictModeReservedWordInClassDeclaration.ts(25,20): error TS2702: 'public' only refers to a type, but is being used as a namespace here. tests/cases/compiler/strictModeReservedWordInClassDeclaration.ts(26,21): error TS1213: Identifier expected. 'public' is a reserved word in strict mode. Class definitions are automatically in strict mode. -tests/cases/compiler/strictModeReservedWordInClassDeclaration.ts(26,21): error TS2693: 'public' only refers to a type, but is being used as a value here. +tests/cases/compiler/strictModeReservedWordInClassDeclaration.ts(26,21): error TS2702: 'public' only refers to a type, but is being used as a namespace here. tests/cases/compiler/strictModeReservedWordInClassDeclaration.ts(27,17): error TS1213: Identifier expected. 'package' is a reserved word in strict mode. Class definitions are automatically in strict mode. tests/cases/compiler/strictModeReservedWordInClassDeclaration.ts(27,17): error TS2304: Cannot find name 'package'. tests/cases/compiler/strictModeReservedWordInClassDeclaration.ts(28,17): error TS1213: Identifier expected. 'package' is a reserved word in strict mode. Class definitions are automatically in strict mode. @@ -88,12 +88,12 @@ tests/cases/compiler/strictModeReservedWordInClassDeclaration.ts(28,17): error T ~~~~~~ !!! error TS1213: Identifier expected. 'public' is a reserved word in strict mode. Class definitions are automatically in strict mode. ~~~~~~ -!!! error TS2693: 'public' only refers to a type, but is being used as a value here. +!!! error TS2702: 'public' only refers to a type, but is being used as a namespace here. class F1 implements public.private.implements { } ~~~~~~ !!! error TS1213: Identifier expected. 'public' is a reserved word in strict mode. Class definitions are automatically in strict mode. ~~~~~~ -!!! error TS2693: 'public' only refers to a type, but is being used as a value here. +!!! error TS2702: 'public' only refers to a type, but is being used as a namespace here. class G extends package { } ~~~~~~~ !!! error TS1213: Identifier expected. 'package' is a reserved word in strict mode. Class definitions are automatically in strict mode. diff --git a/tests/cases/compiler/invalidUseOfTypeAsNamespace.ts b/tests/cases/compiler/invalidUseOfTypeAsNamespace.ts new file mode 100644 index 0000000000..5391715cb3 --- /dev/null +++ b/tests/cases/compiler/invalidUseOfTypeAsNamespace.ts @@ -0,0 +1,4 @@ +interface OhNo { +} + +declare let y: OhNo.hello;