From afbedac94071b4fa028580600c16ff23e08f7004 Mon Sep 17 00:00:00 2001 From: Zzzen Date: Sat, 7 Aug 2021 20:46:22 +0800 Subject: [PATCH 1/3] improve error message for using property of type as type --- src/compiler/checker.ts | 13 +++++-- ...rForUsingPropertyOfTypeAsType01.errors.txt | 38 +++++++++---------- ...rForUsingPropertyOfTypeAsType03.errors.txt | 6 +-- 3 files changed, 32 insertions(+), 25 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index c470ac4c0ddfe..3b1511a5dfe54 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -3197,10 +3197,17 @@ namespace ts { if (!ignoreErrors) { const namespaceName = getFullyQualifiedName(namespace); const declarationName = declarationNameToString(right); - const suggestion = getSuggestedSymbolForNonexistentModule(right, namespace); - suggestion ? - error(right, Diagnostics._0_has_no_exported_member_named_1_Did_you_mean_2, namespaceName, declarationName, symbolToString(suggestion)) : + const suggestionForNonexistentModule = getSuggestedSymbolForNonexistentModule(right, namespace); + const exportedTypeSymbol = getMergedSymbol(getSymbol(getExportsOfSymbol(namespace), right.escapedText, SymbolFlags.Type)); + if (suggestionForNonexistentModule) { + error(right, Diagnostics._0_has_no_exported_member_named_1_Did_you_mean_2, namespaceName, declarationName, symbolToString(suggestionForNonexistentModule)); + } + else if (meaning & SymbolFlags.Namespace && exportedTypeSymbol && isQualifiedName(name.parent)) { + error(name.parent.right, Diagnostics.Cannot_access_0_1_because_0_is_a_type_but_not_a_namespace_Did_you_mean_to_retrieve_the_type_of_the_property_1_in_0_with_0_1, symbolToString(exportedTypeSymbol), unescapeLeadingUnderscores(name.parent.right.escapedText)); + } + else { error(right, Diagnostics.Namespace_0_has_no_exported_member_1, namespaceName, declarationName); + } } return undefined; } diff --git a/tests/baselines/reference/errorForUsingPropertyOfTypeAsType01.errors.txt b/tests/baselines/reference/errorForUsingPropertyOfTypeAsType01.errors.txt index 58f9f2cc6d4ff..6dadb4a4979fe 100644 --- a/tests/baselines/reference/errorForUsingPropertyOfTypeAsType01.errors.txt +++ b/tests/baselines/reference/errorForUsingPropertyOfTypeAsType01.errors.txt @@ -1,15 +1,15 @@ tests/cases/compiler/errorForUsingPropertyOfTypeAsType01.ts(6,12): error TS2713: Cannot access 'Foo.bar' because 'Foo' is a type, but not a namespace. Did you mean to retrieve the type of the property 'bar' in 'Foo' with 'Foo["bar"]'? -tests/cases/compiler/errorForUsingPropertyOfTypeAsType01.ts(7,18): error TS2694: Namespace 'Test1' has no exported member 'Foo'. +tests/cases/compiler/errorForUsingPropertyOfTypeAsType01.ts(7,22): error TS2713: Cannot access 'Foo.bar' because 'Foo' is a type, but not a namespace. Did you mean to retrieve the type of the property 'bar' in 'Foo' with 'Foo["bar"]'? tests/cases/compiler/errorForUsingPropertyOfTypeAsType01.ts(15,12): error TS2713: Cannot access 'Foo.bar' because 'Foo' is a type, but not a namespace. Did you mean to retrieve the type of the property 'bar' in 'Foo' with 'Foo["bar"]'? -tests/cases/compiler/errorForUsingPropertyOfTypeAsType01.ts(16,18): error TS2694: Namespace 'Test2' has no exported member 'Foo'. +tests/cases/compiler/errorForUsingPropertyOfTypeAsType01.ts(16,22): error TS2713: Cannot access 'Foo.bar' because 'Foo' is a type, but not a namespace. Did you mean to retrieve the type of the property 'bar' in 'Foo' with 'Foo["bar"]'? tests/cases/compiler/errorForUsingPropertyOfTypeAsType01.ts(24,12): error TS2713: Cannot access 'Foo.bar' because 'Foo' is a type, but not a namespace. Did you mean to retrieve the type of the property 'bar' in 'Foo' with 'Foo["bar"]'? -tests/cases/compiler/errorForUsingPropertyOfTypeAsType01.ts(25,18): error TS2694: Namespace 'Test3' has no exported member 'Foo'. +tests/cases/compiler/errorForUsingPropertyOfTypeAsType01.ts(25,22): error TS2713: Cannot access 'Foo.bar' because 'Foo' is a type, but not a namespace. Did you mean to retrieve the type of the property 'bar' in 'Foo' with 'Foo["bar"]'? tests/cases/compiler/errorForUsingPropertyOfTypeAsType01.ts(32,12): error TS2713: Cannot access 'Foo.bar' because 'Foo' is a type, but not a namespace. Did you mean to retrieve the type of the property 'bar' in 'Foo' with 'Foo["bar"]'? -tests/cases/compiler/errorForUsingPropertyOfTypeAsType01.ts(33,18): error TS2694: Namespace 'Test4' has no exported member 'Foo'. +tests/cases/compiler/errorForUsingPropertyOfTypeAsType01.ts(33,22): error TS2713: Cannot access 'Foo.bar' because 'Foo' is a type, but not a namespace. Did you mean to retrieve the type of the property 'bar' in 'Foo' with 'Foo["bar"]'? tests/cases/compiler/errorForUsingPropertyOfTypeAsType01.ts(40,12): error TS2702: 'Foo' only refers to a type, but is being used as a namespace here. -tests/cases/compiler/errorForUsingPropertyOfTypeAsType01.ts(41,18): error TS2694: Namespace 'Test5' has no exported member 'Foo'. -tests/cases/compiler/errorForUsingPropertyOfTypeAsType01.ts(44,20): error TS2694: Namespace 'Test5' has no exported member 'Foo'. +tests/cases/compiler/errorForUsingPropertyOfTypeAsType01.ts(41,22): error TS2713: Cannot access 'Foo.bar' because 'Foo' is a type, but not a namespace. Did you mean to retrieve the type of the property 'bar' in 'Foo' with 'Foo["bar"]'? tests/cases/compiler/errorForUsingPropertyOfTypeAsType01.ts(44,24): error TS1003: Identifier expected. +tests/cases/compiler/errorForUsingPropertyOfTypeAsType01.ts(44,24): error TS2713: Cannot access 'Foo.' because 'Foo' is a type, but not a namespace. Did you mean to retrieve the type of the property '' in 'Foo' with 'Foo[""]'? ==== tests/cases/compiler/errorForUsingPropertyOfTypeAsType01.ts (12 errors) ==== @@ -22,8 +22,8 @@ tests/cases/compiler/errorForUsingPropertyOfTypeAsType01.ts(44,24): error TS1003 ~~~~~~~ !!! error TS2713: Cannot access 'Foo.bar' because 'Foo' is a type, but not a namespace. Did you mean to retrieve the type of the property 'bar' in 'Foo' with 'Foo["bar"]'? var y: Test1.Foo.bar = ""; - ~~~ -!!! error TS2694: Namespace 'Test1' has no exported member 'Foo'. + ~~~ +!!! error TS2713: Cannot access 'Foo.bar' because 'Foo' is a type, but not a namespace. Did you mean to retrieve the type of the property 'bar' in 'Foo' with 'Foo["bar"]'? } namespace Test2 { @@ -35,8 +35,8 @@ tests/cases/compiler/errorForUsingPropertyOfTypeAsType01.ts(44,24): error TS1003 ~~~~~~~ !!! error TS2713: Cannot access 'Foo.bar' because 'Foo' is a type, but not a namespace. Did you mean to retrieve the type of the property 'bar' in 'Foo' with 'Foo["bar"]'? var y: Test2.Foo.bar = ""; - ~~~ -!!! error TS2694: Namespace 'Test2' has no exported member 'Foo'. + ~~~ +!!! error TS2713: Cannot access 'Foo.bar' because 'Foo' is a type, but not a namespace. Did you mean to retrieve the type of the property 'bar' in 'Foo' with 'Foo["bar"]'? } namespace Test3 { @@ -48,8 +48,8 @@ tests/cases/compiler/errorForUsingPropertyOfTypeAsType01.ts(44,24): error TS1003 ~~~~~~~ !!! error TS2713: Cannot access 'Foo.bar' because 'Foo' is a type, but not a namespace. Did you mean to retrieve the type of the property 'bar' in 'Foo' with 'Foo["bar"]'? var y: Test3.Foo.bar = ""; - ~~~ -!!! error TS2694: Namespace 'Test3' has no exported member 'Foo'. + ~~~ +!!! error TS2713: Cannot access 'Foo.bar' because 'Foo' is a type, but not a namespace. Did you mean to retrieve the type of the property 'bar' in 'Foo' with 'Foo["bar"]'? } namespace Test4 { @@ -60,8 +60,8 @@ tests/cases/compiler/errorForUsingPropertyOfTypeAsType01.ts(44,24): error TS1003 ~~~~~~~ !!! error TS2713: Cannot access 'Foo.bar' because 'Foo' is a type, but not a namespace. Did you mean to retrieve the type of the property 'bar' in 'Foo' with 'Foo["bar"]'? var y: Test4.Foo.bar = ""; - ~~~ -!!! error TS2694: Namespace 'Test4' has no exported member 'Foo'. + ~~~ +!!! error TS2713: Cannot access 'Foo.bar' because 'Foo' is a type, but not a namespace. Did you mean to retrieve the type of the property 'bar' in 'Foo' with 'Foo["bar"]'? } namespace Test5 { @@ -72,12 +72,12 @@ tests/cases/compiler/errorForUsingPropertyOfTypeAsType01.ts(44,24): error TS1003 ~~~ !!! error TS2702: 'Foo' only refers to a type, but is being used as a namespace here. var y: Test5.Foo.bar = ""; - ~~~ -!!! error TS2694: Namespace 'Test5' has no exported member 'Foo'. + ~~~ +!!! error TS2713: Cannot access 'Foo.bar' because 'Foo' is a type, but not a namespace. Did you mean to retrieve the type of the property 'bar' in 'Foo' with 'Foo["bar"]'? } import lol = Test5.Foo. - ~~~ -!!! error TS2694: Namespace 'Test5' has no exported member 'Foo'. -!!! error TS1003: Identifier expected. \ No newline at end of file +!!! error TS1003: Identifier expected. + +!!! error TS2713: Cannot access 'Foo.' because 'Foo' is a type, but not a namespace. Did you mean to retrieve the type of the property '' in 'Foo' with 'Foo[""]'? \ No newline at end of file diff --git a/tests/baselines/reference/errorForUsingPropertyOfTypeAsType03.errors.txt b/tests/baselines/reference/errorForUsingPropertyOfTypeAsType03.errors.txt index 990a7f425ae9f..03d162d79ad89 100644 --- a/tests/baselines/reference/errorForUsingPropertyOfTypeAsType03.errors.txt +++ b/tests/baselines/reference/errorForUsingPropertyOfTypeAsType03.errors.txt @@ -1,4 +1,4 @@ -tests/cases/compiler/errorForUsingPropertyOfTypeAsType03.ts(11,19): error TS2694: Namespace 'Color' has no exported member 'Red'. +tests/cases/compiler/errorForUsingPropertyOfTypeAsType03.ts(11,23): error TS2713: Cannot access 'Red.toString' because 'Red' is a type, but not a namespace. Did you mean to retrieve the type of the property 'toString' in 'Red' with 'Red["toString"]'? tests/cases/compiler/errorForUsingPropertyOfTypeAsType03.ts(13,19): error TS2339: Property 'Red' does not exist on type 'Color'. tests/cases/compiler/errorForUsingPropertyOfTypeAsType03.ts(19,13): error TS2702: 'C1' only refers to a type, but is being used as a namespace here. tests/cases/compiler/errorForUsingPropertyOfTypeAsType03.ts(20,13): error TS2702: 'C1' only refers to a type, but is being used as a namespace here. @@ -19,8 +19,8 @@ tests/cases/compiler/errorForUsingPropertyOfTypeAsType03.ts(24,13): error TS2713 type C2 = typeof Color; let a1: Color.Red.toString; - ~~~ -!!! error TS2694: Namespace 'Color' has no exported member 'Red'. + ~~~~~~~~ +!!! error TS2713: Cannot access 'Red.toString' because 'Red' is a type, but not a namespace. Did you mean to retrieve the type of the property 'toString' in 'Red' with 'Red["toString"]'? let a2: Color.Red["toString"]; let a3: Color["Red"]["toString"]; ~~~~~ From 58c091608e337285f4bd5b31f4978ed42541da27 Mon Sep 17 00:00:00 2001 From: Zzzen Date: Thu, 2 Sep 2021 22:41:32 +0800 Subject: [PATCH 2/3] suggest typeof when possible --- src/compiler/checker.ts | 29 +++++++++++++++++++ ...rForUsingPropertyOfTypeAsType03.errors.txt | 6 ++-- .../genericFunduleInModule.errors.txt | 6 ++-- .../genericFunduleInModule2.errors.txt | 6 ++-- .../importClause_namespaceImport.errors.txt | 6 ++-- .../reference/parserharness.errors.txt | 6 ++-- 6 files changed, 44 insertions(+), 15 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 3b1511a5dfe54..39ee3c29427cb 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -3148,6 +3148,30 @@ namespace ts { return symbol.parent ? getFullyQualifiedName(symbol.parent, containingLocation) + "." + symbolToString(symbol) : symbolToString(symbol, containingLocation, /*meaning*/ undefined, SymbolFormatFlags.DoNotIncludeSymbolChain | SymbolFormatFlags.AllowAnyNodeKind); } + function getFullQualifiedName(node: QualifiedName) { + while(isQualifiedName(node.parent)) { + node = node.parent; + } + return node; + } + + function tryGetQualifiedNameAsValue(node: QualifiedName) { + let left: Identifier | QualifiedName = getFirstIdentifier(node); + let symbol = resolveName(left, left.escapedText, SymbolFlags.Value, undefined, left, /*isUse*/ true); + if (!symbol) { + return undefined; + } + while (isQualifiedName(left.parent)) { + const type = getTypeOfSymbol(symbol); + symbol = getPropertyOfType(type, left.parent.right.escapedText); + if (!symbol) { + return undefined; + } + left = left.parent; + } + return symbol; + } + /** * Resolves a qualified name and any involved aliases. */ @@ -3199,9 +3223,14 @@ namespace ts { const declarationName = declarationNameToString(right); const suggestionForNonexistentModule = getSuggestedSymbolForNonexistentModule(right, namespace); const exportedTypeSymbol = getMergedSymbol(getSymbol(getExportsOfSymbol(namespace), right.escapedText, SymbolFlags.Type)); + const fullQualifiedName = isQualifiedName(name) && getFullQualifiedName(name); + const canSuggestTypeof = fullQualifiedName && !isTypeOfExpression(fullQualifiedName.parent) && tryGetQualifiedNameAsValue(fullQualifiedName); if (suggestionForNonexistentModule) { error(right, Diagnostics._0_has_no_exported_member_named_1_Did_you_mean_2, namespaceName, declarationName, symbolToString(suggestionForNonexistentModule)); } + else if (canSuggestTypeof) { + error(name, Diagnostics._0_refers_to_a_value_but_is_being_used_as_a_type_here_Did_you_mean_typeof_0, entityNameToString(fullQualifiedName as QualifiedName)); + } else if (meaning & SymbolFlags.Namespace && exportedTypeSymbol && isQualifiedName(name.parent)) { error(name.parent.right, Diagnostics.Cannot_access_0_1_because_0_is_a_type_but_not_a_namespace_Did_you_mean_to_retrieve_the_type_of_the_property_1_in_0_with_0_1, symbolToString(exportedTypeSymbol), unescapeLeadingUnderscores(name.parent.right.escapedText)); } diff --git a/tests/baselines/reference/errorForUsingPropertyOfTypeAsType03.errors.txt b/tests/baselines/reference/errorForUsingPropertyOfTypeAsType03.errors.txt index 03d162d79ad89..1bfd5064a73f1 100644 --- a/tests/baselines/reference/errorForUsingPropertyOfTypeAsType03.errors.txt +++ b/tests/baselines/reference/errorForUsingPropertyOfTypeAsType03.errors.txt @@ -1,4 +1,4 @@ -tests/cases/compiler/errorForUsingPropertyOfTypeAsType03.ts(11,23): error TS2713: Cannot access 'Red.toString' because 'Red' is a type, but not a namespace. Did you mean to retrieve the type of the property 'toString' in 'Red' with 'Red["toString"]'? +tests/cases/compiler/errorForUsingPropertyOfTypeAsType03.ts(11,13): error TS2749: 'Color.Red.toString' refers to a value, but is being used as a type here. Did you mean 'typeof Color.Red.toString'? tests/cases/compiler/errorForUsingPropertyOfTypeAsType03.ts(13,19): error TS2339: Property 'Red' does not exist on type 'Color'. tests/cases/compiler/errorForUsingPropertyOfTypeAsType03.ts(19,13): error TS2702: 'C1' only refers to a type, but is being used as a namespace here. tests/cases/compiler/errorForUsingPropertyOfTypeAsType03.ts(20,13): error TS2702: 'C1' only refers to a type, but is being used as a namespace here. @@ -19,8 +19,8 @@ tests/cases/compiler/errorForUsingPropertyOfTypeAsType03.ts(24,13): error TS2713 type C2 = typeof Color; let a1: Color.Red.toString; - ~~~~~~~~ -!!! error TS2713: Cannot access 'Red.toString' because 'Red' is a type, but not a namespace. Did you mean to retrieve the type of the property 'toString' in 'Red' with 'Red["toString"]'? + ~~~~~~~~~ +!!! error TS2749: 'Color.Red.toString' refers to a value, but is being used as a type here. Did you mean 'typeof Color.Red.toString'? let a2: Color.Red["toString"]; let a3: Color["Red"]["toString"]; ~~~~~ diff --git a/tests/baselines/reference/genericFunduleInModule.errors.txt b/tests/baselines/reference/genericFunduleInModule.errors.txt index c3c9f0247447e..2aba9006a6f01 100644 --- a/tests/baselines/reference/genericFunduleInModule.errors.txt +++ b/tests/baselines/reference/genericFunduleInModule.errors.txt @@ -1,4 +1,4 @@ -tests/cases/compiler/genericFunduleInModule.ts(8,10): error TS2694: Namespace 'A' has no exported member 'B'. +tests/cases/compiler/genericFunduleInModule.ts(8,8): error TS2749: 'A.B' refers to a value, but is being used as a type here. Did you mean 'typeof A.B'? ==== tests/cases/compiler/genericFunduleInModule.ts (1 errors) ==== @@ -10,6 +10,6 @@ tests/cases/compiler/genericFunduleInModule.ts(8,10): error TS2694: Namespace 'A } var b: A.B; - ~ -!!! error TS2694: Namespace 'A' has no exported member 'B'. + ~~~ +!!! error TS2749: 'A.B' refers to a value, but is being used as a type here. Did you mean 'typeof A.B'? A.B(1); \ No newline at end of file diff --git a/tests/baselines/reference/genericFunduleInModule2.errors.txt b/tests/baselines/reference/genericFunduleInModule2.errors.txt index 3184d02f72308..8e6852565db55 100644 --- a/tests/baselines/reference/genericFunduleInModule2.errors.txt +++ b/tests/baselines/reference/genericFunduleInModule2.errors.txt @@ -1,4 +1,4 @@ -tests/cases/compiler/genericFunduleInModule2.ts(11,10): error TS2694: Namespace 'A' has no exported member 'B'. +tests/cases/compiler/genericFunduleInModule2.ts(11,8): error TS2749: 'A.B' refers to a value, but is being used as a type here. Did you mean 'typeof A.B'? ==== tests/cases/compiler/genericFunduleInModule2.ts (1 errors) ==== @@ -13,6 +13,6 @@ tests/cases/compiler/genericFunduleInModule2.ts(11,10): error TS2694: Namespace } var b: A.B; - ~ -!!! error TS2694: Namespace 'A' has no exported member 'B'. + ~~~ +!!! error TS2749: 'A.B' refers to a value, but is being used as a type here. Did you mean 'typeof A.B'? A.B(1); \ No newline at end of file diff --git a/tests/baselines/reference/importClause_namespaceImport.errors.txt b/tests/baselines/reference/importClause_namespaceImport.errors.txt index 4958d7a5bf58c..b1f70200bee1a 100644 --- a/tests/baselines/reference/importClause_namespaceImport.errors.txt +++ b/tests/baselines/reference/importClause_namespaceImport.errors.txt @@ -1,6 +1,6 @@ /b.ts(2,1): error TS1361: 'types' cannot be used as a value because it was imported using 'import type'. /b.ts(3,1): error TS1361: 'types' cannot be used as a value because it was imported using 'import type'. -/b.ts(4,14): error TS2694: Namespace '"/a"' has no exported member 'Value'. +/b.ts(4,8): error TS2749: 'types.Value' refers to a value, but is being used as a type here. Did you mean 'typeof types.Value'? /b.ts(5,7): error TS2741: Property 'a' is missing in type '{}' but required in type 'A'. /b.ts(6,7): error TS2741: Property 'b' is missing in type '{}' but required in type 'B'. /b.ts(8,13): error TS1361: 'types' cannot be used as a value because it was imported using 'import type'. @@ -23,8 +23,8 @@ !!! error TS1361: 'types' cannot be used as a value because it was imported using 'import type'. !!! related TS1376 /b.ts:1:18: 'types' was imported here. let v: types.Value; - ~~~~~ -!!! error TS2694: Namespace '"/a"' has no exported member 'Value'. + ~~~~~~~~~~~ +!!! error TS2749: 'types.Value' refers to a value, but is being used as a type here. Did you mean 'typeof types.Value'? const a: types.A = {}; ~ !!! error TS2741: Property 'a' is missing in type '{}' but required in type 'A'. diff --git a/tests/baselines/reference/parserharness.errors.txt b/tests/baselines/reference/parserharness.errors.txt index 012f080d0d055..c3cb53f4b1797 100644 --- a/tests/baselines/reference/parserharness.errors.txt +++ b/tests/baselines/reference/parserharness.errors.txt @@ -2,7 +2,7 @@ tests/cases/conformance/parser/ecmascript5/RealWorld/parserharness.ts(16,21): er tests/cases/conformance/parser/ecmascript5/RealWorld/parserharness.ts(17,21): error TS6053: File 'tests/cases/conformance/parser/ecmascript5/compiler/typescript.ts' not found. tests/cases/conformance/parser/ecmascript5/RealWorld/parserharness.ts(18,21): error TS6053: File 'tests/cases/conformance/parser/ecmascript5/services/typescriptServices.ts' not found. tests/cases/conformance/parser/ecmascript5/RealWorld/parserharness.ts(19,21): error TS6053: File 'tests/cases/conformance/parser/ecmascript5/RealWorld/diff.ts' not found. -tests/cases/conformance/parser/ecmascript5/RealWorld/parserharness.ts(21,29): error TS2694: Namespace 'Harness' has no exported member 'Assert'. +tests/cases/conformance/parser/ecmascript5/RealWorld/parserharness.ts(21,21): error TS2749: 'Harness.Assert' refers to a value, but is being used as a type here. Did you mean 'typeof Harness.Assert'? tests/cases/conformance/parser/ecmascript5/RealWorld/parserharness.ts(25,17): error TS2304: Cannot find name 'IIO'. tests/cases/conformance/parser/ecmascript5/RealWorld/parserharness.ts(41,12): error TS2304: Cannot find name 'ActiveXObject'. tests/cases/conformance/parser/ecmascript5/RealWorld/parserharness.ts(43,19): error TS2580: Cannot find name 'require'. Do you need to install type definitions for node? Try `npm i --save-dev @types/node`. @@ -140,8 +140,8 @@ tests/cases/conformance/parser/ecmascript5/RealWorld/parserharness.ts(2030,32): !!! error TS6053: File 'tests/cases/conformance/parser/ecmascript5/RealWorld/diff.ts' not found. declare var assert: Harness.Assert; - ~~~~~~ -!!! error TS2694: Namespace 'Harness' has no exported member 'Assert'. + ~~~~~~~~~~~~~~ +!!! error TS2749: 'Harness.Assert' refers to a value, but is being used as a type here. Did you mean 'typeof Harness.Assert'? declare var it; declare var describe; declare var run; From 2b9c8f5d7d063139626025f8b49f25915312c7c2 Mon Sep 17 00:00:00 2001 From: Zzzen Date: Fri, 3 Sep 2021 21:20:57 +0800 Subject: [PATCH 3/3] fix naming and error location --- src/compiler/checker.ts | 10 +++++----- .../errorForUsingPropertyOfTypeAsType03.errors.txt | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 39ee3c29427cb..aaab38b5c0fa2 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -3148,8 +3148,8 @@ namespace ts { return symbol.parent ? getFullyQualifiedName(symbol.parent, containingLocation) + "." + symbolToString(symbol) : symbolToString(symbol, containingLocation, /*meaning*/ undefined, SymbolFormatFlags.DoNotIncludeSymbolChain | SymbolFormatFlags.AllowAnyNodeKind); } - function getFullQualifiedName(node: QualifiedName) { - while(isQualifiedName(node.parent)) { + function getContainingQualifiedNameNode(node: QualifiedName) { + while (isQualifiedName(node.parent)) { node = node.parent; } return node; @@ -3223,13 +3223,13 @@ namespace ts { const declarationName = declarationNameToString(right); const suggestionForNonexistentModule = getSuggestedSymbolForNonexistentModule(right, namespace); const exportedTypeSymbol = getMergedSymbol(getSymbol(getExportsOfSymbol(namespace), right.escapedText, SymbolFlags.Type)); - const fullQualifiedName = isQualifiedName(name) && getFullQualifiedName(name); - const canSuggestTypeof = fullQualifiedName && !isTypeOfExpression(fullQualifiedName.parent) && tryGetQualifiedNameAsValue(fullQualifiedName); + const containingQualifiedName = isQualifiedName(name) && getContainingQualifiedNameNode(name); + const canSuggestTypeof = containingQualifiedName && !isTypeOfExpression(containingQualifiedName.parent) && tryGetQualifiedNameAsValue(containingQualifiedName); if (suggestionForNonexistentModule) { error(right, Diagnostics._0_has_no_exported_member_named_1_Did_you_mean_2, namespaceName, declarationName, symbolToString(suggestionForNonexistentModule)); } else if (canSuggestTypeof) { - error(name, Diagnostics._0_refers_to_a_value_but_is_being_used_as_a_type_here_Did_you_mean_typeof_0, entityNameToString(fullQualifiedName as QualifiedName)); + error(containingQualifiedName, Diagnostics._0_refers_to_a_value_but_is_being_used_as_a_type_here_Did_you_mean_typeof_0, entityNameToString(containingQualifiedName)); } else if (meaning & SymbolFlags.Namespace && exportedTypeSymbol && isQualifiedName(name.parent)) { error(name.parent.right, Diagnostics.Cannot_access_0_1_because_0_is_a_type_but_not_a_namespace_Did_you_mean_to_retrieve_the_type_of_the_property_1_in_0_with_0_1, symbolToString(exportedTypeSymbol), unescapeLeadingUnderscores(name.parent.right.escapedText)); diff --git a/tests/baselines/reference/errorForUsingPropertyOfTypeAsType03.errors.txt b/tests/baselines/reference/errorForUsingPropertyOfTypeAsType03.errors.txt index 1bfd5064a73f1..bcd587f85a637 100644 --- a/tests/baselines/reference/errorForUsingPropertyOfTypeAsType03.errors.txt +++ b/tests/baselines/reference/errorForUsingPropertyOfTypeAsType03.errors.txt @@ -19,7 +19,7 @@ tests/cases/compiler/errorForUsingPropertyOfTypeAsType03.ts(24,13): error TS2713 type C2 = typeof Color; let a1: Color.Red.toString; - ~~~~~~~~~ + ~~~~~~~~~~~~~~~~~~ !!! error TS2749: 'Color.Red.toString' refers to a value, but is being used as a type here. Did you mean 'typeof Color.Red.toString'? let a2: Color.Red["toString"]; let a3: Color["Red"]["toString"];