improve error message for using property of type as type (#45354)
* improve error message for using property of type as type * suggest typeof when possible * fix naming and error location
This commit is contained in:
parent
d514a69409
commit
1d51dfa550
|
@ -3156,6 +3156,30 @@ namespace ts {
|
|||
return symbol.parent ? getFullyQualifiedName(symbol.parent, containingLocation) + "." + symbolToString(symbol) : symbolToString(symbol, containingLocation, /*meaning*/ undefined, SymbolFormatFlags.DoNotIncludeSymbolChain | SymbolFormatFlags.AllowAnyNodeKind);
|
||||
}
|
||||
|
||||
function getContainingQualifiedNameNode(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.
|
||||
*/
|
||||
|
@ -3205,10 +3229,22 @@ 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));
|
||||
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(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));
|
||||
}
|
||||
else {
|
||||
error(right, Diagnostics.Namespace_0_has_no_exported_member_1, namespaceName, declarationName);
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
!!! 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[""]'?
|
|
@ -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,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 TS2694: Namespace 'Color' has no exported member 'Red'.
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
!!! 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"];
|
||||
~~~~~
|
||||
|
|
|
@ -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);
|
|
@ -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);
|
|
@ -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'.
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue