From 72a7d41204e73e04bf465c90d985770bb4774b9f Mon Sep 17 00:00:00 2001 From: John Patterson Date: Wed, 24 Jul 2019 09:36:30 -0700 Subject: [PATCH] adds error message for using value as type argument This addresses issue #28975 (https://github.com/microsoft/TypeScript/issues/28975). When providing a value as a type argument, we can suggest a more specific error message: "Did you mean to use typeof T?" adds error message WIP: Detect error WIP: progress updated tests janky implementation adds test coverage around literal types being unaffected refactor out isIdentifierATypeArgument function adds test case for type alias adds test case for nested type arguments fixes linting errors merge master into branch to overwrite changes changes value as type error message This suggests 'typeof T' as a potential alternative when we give an error about using value T as a type. remove stale tests from old change --- src/compiler/checker.ts | 2 +- src/compiler/diagnosticMessages.json | 2 +- ...owImportClausesToMergeWithTypes.errors.txt | 4 ++-- .../baselines/reference/intrinsics.errors.txt | 4 ++-- ...serAmbiguityWithBinaryOperator4.errors.txt | 8 ++++---- .../reference/typeAssertions.errors.txt | 8 ++++---- .../typeGuardFunctionErrors.errors.txt | 20 +++++++++---------- 7 files changed, 24 insertions(+), 24 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index fba39a2b5d93f..90dbac991aafb 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2109,7 +2109,7 @@ namespace ts { if (meaning & (SymbolFlags.Type & ~SymbolFlags.Namespace)) { const symbol = resolveSymbol(resolveName(errorLocation, name, ~SymbolFlags.Type & SymbolFlags.Value, /*nameNotFoundMessage*/undefined, /*nameArg*/ undefined, /*isUse*/ false)); if (symbol && !(symbol.flags & SymbolFlags.Namespace)) { - error(errorLocation, Diagnostics._0_refers_to_a_value_but_is_being_used_as_a_type_here, unescapeLeadingUnderscores(name)); + error(errorLocation, Diagnostics._0_refers_to_a_value_but_is_being_used_as_a_type_here_Did_you_mean_typeof_0, unescapeLeadingUnderscores(name)); return true; } } diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index c8bd3ceb7b79b..b4b968301010a 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -2763,7 +2763,7 @@ "category": "Error", "code": 2748 }, - "'{0}' refers to a value, but is being used as a type here.": { + "'{0}' refers to a value, but is being used as a type here. Did you mean 'typeof {0}'?": { "category": "Error", "code": 2749 }, diff --git a/tests/baselines/reference/allowImportClausesToMergeWithTypes.errors.txt b/tests/baselines/reference/allowImportClausesToMergeWithTypes.errors.txt index 8c4f995531047..63cb28ea7d626 100644 --- a/tests/baselines/reference/allowImportClausesToMergeWithTypes.errors.txt +++ b/tests/baselines/reference/allowImportClausesToMergeWithTypes.errors.txt @@ -1,5 +1,5 @@ tests/cases/compiler/index.ts(4,1): error TS2693: 'zzz' only refers to a type, but is being used as a value here. -tests/cases/compiler/index.ts(9,10): error TS2749: 'originalZZZ' refers to a value, but is being used as a type here. +tests/cases/compiler/index.ts(9,10): error TS2749: 'originalZZZ' refers to a value, but is being used as a type here. Did you mean 'typeof originalZZZ'? ==== tests/cases/compiler/b.ts (0 errors) ==== @@ -31,4 +31,4 @@ tests/cases/compiler/index.ts(9,10): error TS2749: 'originalZZZ' refers to a val const y: originalZZZ = x; ~~~~~~~~~~~ -!!! error TS2749: 'originalZZZ' refers to a value, but is being used as a type here. \ No newline at end of file +!!! error TS2749: 'originalZZZ' refers to a value, but is being used as a type here. Did you mean 'typeof originalZZZ'? \ No newline at end of file diff --git a/tests/baselines/reference/intrinsics.errors.txt b/tests/baselines/reference/intrinsics.errors.txt index 13d61dacbcf97..ef86f505ed27e 100644 --- a/tests/baselines/reference/intrinsics.errors.txt +++ b/tests/baselines/reference/intrinsics.errors.txt @@ -1,4 +1,4 @@ -tests/cases/compiler/intrinsics.ts(1,21): error TS2749: 'hasOwnProperty' refers to a value, but is being used as a type here. +tests/cases/compiler/intrinsics.ts(1,21): error TS2749: 'hasOwnProperty' refers to a value, but is being used as a type here. Did you mean 'typeof hasOwnProperty'? tests/cases/compiler/intrinsics.ts(1,21): error TS4025: Exported variable 'hasOwnProperty' has or is using private name 'hasOwnProperty'. tests/cases/compiler/intrinsics.ts(10,1): error TS2304: Cannot find name '__proto__'. @@ -6,7 +6,7 @@ tests/cases/compiler/intrinsics.ts(10,1): error TS2304: Cannot find name '__prot ==== tests/cases/compiler/intrinsics.ts (3 errors) ==== var hasOwnProperty: hasOwnProperty; // Error ~~~~~~~~~~~~~~ -!!! error TS2749: 'hasOwnProperty' refers to a value, but is being used as a type here. +!!! error TS2749: 'hasOwnProperty' refers to a value, but is being used as a type here. Did you mean 'typeof hasOwnProperty'? ~~~~~~~~~~~~~~ !!! error TS4025: Exported variable 'hasOwnProperty' has or is using private name 'hasOwnProperty'. diff --git a/tests/baselines/reference/parserAmbiguityWithBinaryOperator4.errors.txt b/tests/baselines/reference/parserAmbiguityWithBinaryOperator4.errors.txt index a94b60e5f996d..af2167f777f0f 100644 --- a/tests/baselines/reference/parserAmbiguityWithBinaryOperator4.errors.txt +++ b/tests/baselines/reference/parserAmbiguityWithBinaryOperator4.errors.txt @@ -1,6 +1,6 @@ tests/cases/conformance/parser/ecmascript5/Generics/parserAmbiguityWithBinaryOperator4.ts(3,9): error TS2347: Untyped function calls may not accept type arguments. -tests/cases/conformance/parser/ecmascript5/Generics/parserAmbiguityWithBinaryOperator4.ts(3,11): error TS2749: 'b' refers to a value, but is being used as a type here. -tests/cases/conformance/parser/ecmascript5/Generics/parserAmbiguityWithBinaryOperator4.ts(3,14): error TS2749: 'b' refers to a value, but is being used as a type here. +tests/cases/conformance/parser/ecmascript5/Generics/parserAmbiguityWithBinaryOperator4.ts(3,11): error TS2749: 'b' refers to a value, but is being used as a type here. Did you mean 'typeof b'? +tests/cases/conformance/parser/ecmascript5/Generics/parserAmbiguityWithBinaryOperator4.ts(3,14): error TS2749: 'b' refers to a value, but is being used as a type here. Did you mean 'typeof b'? ==== tests/cases/conformance/parser/ecmascript5/Generics/parserAmbiguityWithBinaryOperator4.ts (3 errors) ==== @@ -10,7 +10,7 @@ tests/cases/conformance/parser/ecmascript5/Generics/parserAmbiguityWithBinaryOpe ~~~~~~~~~~~~~~ !!! error TS2347: Untyped function calls may not accept type arguments. ~ -!!! error TS2749: 'b' refers to a value, but is being used as a type here. +!!! error TS2749: 'b' refers to a value, but is being used as a type here. Did you mean 'typeof b'? ~ -!!! error TS2749: 'b' refers to a value, but is being used as a type here. +!!! error TS2749: 'b' refers to a value, but is being used as a type here. Did you mean 'typeof b'? } \ No newline at end of file diff --git a/tests/baselines/reference/typeAssertions.errors.txt b/tests/baselines/reference/typeAssertions.errors.txt index ef9a23b8d8ae4..9d10ec17fe95d 100644 --- a/tests/baselines/reference/typeAssertions.errors.txt +++ b/tests/baselines/reference/typeAssertions.errors.txt @@ -7,7 +7,7 @@ tests/cases/conformance/expressions/typeAssertions/typeAssertions.ts(37,13): err Property 'q' is missing in type 'SomeDerived' but required in type 'SomeOther'. tests/cases/conformance/expressions/typeAssertions/typeAssertions.ts(38,13): error TS2352: Conversion of type 'SomeBase' to type 'SomeOther' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first. Property 'q' is missing in type 'SomeBase' but required in type 'SomeOther'. -tests/cases/conformance/expressions/typeAssertions/typeAssertions.ts(44,5): error TS2749: 'numOrStr' refers to a value, but is being used as a type here. +tests/cases/conformance/expressions/typeAssertions/typeAssertions.ts(44,5): error TS2749: 'numOrStr' refers to a value, but is being used as a type here. Did you mean 'typeof numOrStr'? tests/cases/conformance/expressions/typeAssertions/typeAssertions.ts(44,14): error TS1005: '>' expected. tests/cases/conformance/expressions/typeAssertions/typeAssertions.ts(44,14): error TS2304: Cannot find name 'is'. tests/cases/conformance/expressions/typeAssertions/typeAssertions.ts(44,17): error TS1005: ')' expected. @@ -15,7 +15,7 @@ tests/cases/conformance/expressions/typeAssertions/typeAssertions.ts(44,17): err tests/cases/conformance/expressions/typeAssertions/typeAssertions.ts(44,48): error TS1005: ';' expected. tests/cases/conformance/expressions/typeAssertions/typeAssertions.ts(45,2): error TS2322: Type 'string | number' is not assignable to type 'string'. Type 'number' is not assignable to type 'string'. -tests/cases/conformance/expressions/typeAssertions/typeAssertions.ts(48,32): error TS2749: 'numOrStr' refers to a value, but is being used as a type here. +tests/cases/conformance/expressions/typeAssertions/typeAssertions.ts(48,32): error TS2749: 'numOrStr' refers to a value, but is being used as a type here. Did you mean 'typeof numOrStr'? tests/cases/conformance/expressions/typeAssertions/typeAssertions.ts(48,41): error TS1005: ')' expected. tests/cases/conformance/expressions/typeAssertions/typeAssertions.ts(48,41): error TS2304: Cannot find name 'is'. tests/cases/conformance/expressions/typeAssertions/typeAssertions.ts(48,44): error TS1005: ';' expected. @@ -86,7 +86,7 @@ tests/cases/conformance/expressions/typeAssertions/typeAssertions.ts(48,50): err var str: string; if((numOrStr === undefined)) { // Error ~~~~~~~~ -!!! error TS2749: 'numOrStr' refers to a value, but is being used as a type here. +!!! error TS2749: 'numOrStr' refers to a value, but is being used as a type here. Did you mean 'typeof numOrStr'? ~~ !!! error TS1005: '>' expected. ~~ @@ -105,7 +105,7 @@ tests/cases/conformance/expressions/typeAssertions/typeAssertions.ts(48,50): err if((numOrStr === undefined) as numOrStr is string) { // Error ~~~~~~~~ -!!! error TS2749: 'numOrStr' refers to a value, but is being used as a type here. +!!! error TS2749: 'numOrStr' refers to a value, but is being used as a type here. Did you mean 'typeof numOrStr'? ~~ !!! error TS1005: ')' expected. ~~ diff --git a/tests/baselines/reference/typeGuardFunctionErrors.errors.txt b/tests/baselines/reference/typeGuardFunctionErrors.errors.txt index 6f24585a85f2b..2f3e7eb1862ed 100644 --- a/tests/baselines/reference/typeGuardFunctionErrors.errors.txt +++ b/tests/baselines/reference/typeGuardFunctionErrors.errors.txt @@ -1,10 +1,10 @@ tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(1,7): error TS2300: Duplicate identifier 'A'. tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(14,5): error TS2322: Type '""' is not assignable to type 'boolean'. -tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(17,55): error TS2749: 'x' refers to a value, but is being used as a type here. +tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(17,55): error TS2749: 'x' refers to a value, but is being used as a type here. Did you mean 'typeof x'? tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(17,57): error TS1144: '{' or ';' expected. tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(17,60): error TS1005: ';' expected. tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(17,62): error TS1005: ';' expected. -tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(21,33): error TS2749: 'x' refers to a value, but is being used as a type here. +tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(21,33): error TS2749: 'x' refers to a value, but is being used as a type here. Did you mean 'typeof x'? tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(25,33): error TS1225: Cannot find parameter 'x'. tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(29,10): error TS2391: Function implementation is missing or not immediately following the declaration. tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(30,5): error TS1131: Property or signature expected. @@ -28,14 +28,14 @@ tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(84,1): Type predicate 'p2 is A' is not assignable to 'p1 is A'. Parameter 'p2' is not in the same position as parameter 'p1'. tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(90,1): error TS2322: Type '(p1: any, p2: any, p3: any) => p1 is A' is not assignable to type '(p1: any, p2: any) => p1 is A'. -tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(95,9): error TS2749: 'b' refers to a value, but is being used as a type here. +tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(95,9): error TS2749: 'b' refers to a value, but is being used as a type here. Did you mean 'typeof b'? tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(95,11): error TS1005: ',' expected. tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(95,14): error TS1005: ',' expected. tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(95,14): error TS2300: Duplicate identifier 'A'. -tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(96,16): error TS2749: 'b' refers to a value, but is being used as a type here. +tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(96,16): error TS2749: 'b' refers to a value, but is being used as a type here. Did you mean 'typeof b'? tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(96,18): error TS1005: ',' expected. tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(96,21): error TS1005: ',' expected. -tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(97,20): error TS2749: 'b' refers to a value, but is being used as a type here. +tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(97,20): error TS2749: 'b' refers to a value, but is being used as a type here. Did you mean 'typeof b'? tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(97,22): error TS1144: '{' or ';' expected. tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(97,25): error TS1005: ';' expected. tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(97,27): error TS1005: ';' expected. @@ -91,7 +91,7 @@ tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(166,54 function hasTypeGuardTypeInsideTypeGuardType(x): x is x is A { ~ -!!! error TS2749: 'x' refers to a value, but is being used as a type here. +!!! error TS2749: 'x' refers to a value, but is being used as a type here. Did you mean 'typeof x'? ~~ !!! error TS1144: '{' or ';' expected. ~ @@ -103,7 +103,7 @@ tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(166,54 function hasMissingIsKeyword(): x { ~ -!!! error TS2749: 'x' refers to a value, but is being used as a type here. +!!! error TS2749: 'x' refers to a value, but is being used as a type here. Did you mean 'typeof x'? return true; } @@ -222,7 +222,7 @@ tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(166,54 // Type predicates in non-return type positions var b1: b is A; ~ -!!! error TS2749: 'b' refers to a value, but is being used as a type here. +!!! error TS2749: 'b' refers to a value, but is being used as a type here. Did you mean 'typeof b'? ~~ !!! error TS1005: ',' expected. ~ @@ -231,14 +231,14 @@ tests/cases/conformance/expressions/typeGuards/typeGuardFunctionErrors.ts(166,54 !!! error TS2300: Duplicate identifier 'A'. function b2(a: b is A) {}; ~ -!!! error TS2749: 'b' refers to a value, but is being used as a type here. +!!! error TS2749: 'b' refers to a value, but is being used as a type here. Did you mean 'typeof b'? ~~ !!! error TS1005: ',' expected. ~ !!! error TS1005: ',' expected. function b3(): A | b is A { ~ -!!! error TS2749: 'b' refers to a value, but is being used as a type here. +!!! error TS2749: 'b' refers to a value, but is being used as a type here. Did you mean 'typeof b'? ~~ !!! error TS1144: '{' or ';' expected. ~