mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
fix(25770): add diagnostic message for the possible mapped type used as an index (#39973)
This commit is contained in:
+20
-4
@@ -2243,16 +2243,32 @@ namespace ts {
|
||||
}
|
||||
const symbol = resolveSymbol(resolveName(errorLocation, name, SymbolFlags.Type & ~SymbolFlags.Value, /*nameNotFoundMessage*/undefined, /*nameArg*/ undefined, /*isUse*/ false));
|
||||
if (symbol && !(symbol.flags & SymbolFlags.NamespaceModule)) {
|
||||
const message = isES2015OrLaterConstructorName(name)
|
||||
? Diagnostics._0_only_refers_to_a_type_but_is_being_used_as_a_value_here_Do_you_need_to_change_your_target_library_Try_changing_the_lib_compiler_option_to_es2015_or_later
|
||||
: Diagnostics._0_only_refers_to_a_type_but_is_being_used_as_a_value_here;
|
||||
error(errorLocation, message, unescapeLeadingUnderscores(name));
|
||||
const rawName = unescapeLeadingUnderscores(name);
|
||||
if (isES2015OrLaterConstructorName(name)) {
|
||||
error(errorLocation, Diagnostics._0_only_refers_to_a_type_but_is_being_used_as_a_value_here_Do_you_need_to_change_your_target_library_Try_changing_the_lib_compiler_option_to_es2015_or_later, rawName);
|
||||
}
|
||||
else if (maybeMappedType(errorLocation, symbol)) {
|
||||
error(errorLocation, Diagnostics._0_only_refers_to_a_type_but_is_being_used_as_a_value_here_Did_you_mean_to_use_1_in_0, rawName, rawName === "K" ? "P" : "K");
|
||||
}
|
||||
else {
|
||||
error(errorLocation, Diagnostics._0_only_refers_to_a_type_but_is_being_used_as_a_value_here, rawName);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function maybeMappedType(node: Node, symbol: Symbol) {
|
||||
const container = findAncestor(node.parent, n =>
|
||||
isComputedPropertyName(n) || isPropertySignature(n) ? false : isTypeLiteralNode(n) || "quit") as TypeLiteralNode | undefined;
|
||||
if (container && container.members.length === 1) {
|
||||
const type = getDeclaredTypeOfSymbol(symbol);
|
||||
return !!(type.flags & TypeFlags.Union) && allTypesAssignableToKind(type, TypeFlags.StringOrNumberLiteral, /*strict*/ true);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function isES2015OrLaterConstructorName(n: __String) {
|
||||
switch (n) {
|
||||
case "Promise":
|
||||
|
||||
@@ -2607,6 +2607,10 @@
|
||||
"category": "Error",
|
||||
"code": 2689
|
||||
},
|
||||
"'{0}' only refers to a type, but is being used as a value here. Did you mean to use '{1} in {0}'?": {
|
||||
"category": "Error",
|
||||
"code": 2690
|
||||
},
|
||||
"An import path cannot end with a '{0}' extension. Consider importing '{1}' instead.": {
|
||||
"category": "Error",
|
||||
"code": 2691
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
tests/cases/compiler/typeUsedAsTypeLiteralIndex.ts(3,5): error TS1170: A computed property name in a type literal must refer to an expression whose type is a literal type or a 'unique symbol' type.
|
||||
tests/cases/compiler/typeUsedAsTypeLiteralIndex.ts(3,6): error TS2690: 'K' only refers to a type, but is being used as a value here. Did you mean to use 'P in K'?
|
||||
tests/cases/compiler/typeUsedAsTypeLiteralIndex.ts(13,5): error TS1170: A computed property name in a type literal must refer to an expression whose type is a literal type or a 'unique symbol' type.
|
||||
tests/cases/compiler/typeUsedAsTypeLiteralIndex.ts(13,6): error TS2690: 'K2' only refers to a type, but is being used as a value here. Did you mean to use 'K in K2'?
|
||||
tests/cases/compiler/typeUsedAsTypeLiteralIndex.ts(18,5): error TS1170: A computed property name in a type literal must refer to an expression whose type is a literal type or a 'unique symbol' type.
|
||||
tests/cases/compiler/typeUsedAsTypeLiteralIndex.ts(18,6): error TS2690: 'K3' only refers to a type, but is being used as a value here. Did you mean to use 'K in K3'?
|
||||
tests/cases/compiler/typeUsedAsTypeLiteralIndex.ts(23,5): error TS1170: A computed property name in a type literal must refer to an expression whose type is a literal type or a 'unique symbol' type.
|
||||
tests/cases/compiler/typeUsedAsTypeLiteralIndex.ts(23,6): error TS2693: 'K4' only refers to a type, but is being used as a value here.
|
||||
|
||||
|
||||
==== tests/cases/compiler/typeUsedAsTypeLiteralIndex.ts (8 errors) ====
|
||||
type K = number | string;
|
||||
type T = {
|
||||
[K]: number; // Did you mean to use 'P in K'?
|
||||
~~~
|
||||
!!! error TS1170: A computed property name in a type literal must refer to an expression whose type is a literal type or a 'unique symbol' type.
|
||||
~
|
||||
!!! error TS2690: 'K' only refers to a type, but is being used as a value here. Did you mean to use 'P in K'?
|
||||
}
|
||||
|
||||
const K1 = Symbol();
|
||||
type T1 = {
|
||||
[K1]: number;
|
||||
}
|
||||
|
||||
type K2 = "x" | "y";
|
||||
type T2 = {
|
||||
[K2]: number; // Did you mean to use 'K in K2'?
|
||||
~~~~
|
||||
!!! error TS1170: A computed property name in a type literal must refer to an expression whose type is a literal type or a 'unique symbol' type.
|
||||
~~
|
||||
!!! error TS2690: 'K2' only refers to a type, but is being used as a value here. Did you mean to use 'K in K2'?
|
||||
}
|
||||
|
||||
type K3 = number | string;
|
||||
type T3 = {
|
||||
[K3]: number; // Did you mean to use 'K in K3'?
|
||||
~~~~
|
||||
!!! error TS1170: A computed property name in a type literal must refer to an expression whose type is a literal type or a 'unique symbol' type.
|
||||
~~
|
||||
!!! error TS2690: 'K3' only refers to a type, but is being used as a value here. Did you mean to use 'K in K3'?
|
||||
}
|
||||
|
||||
type K4 = number | string;
|
||||
type T4 = {
|
||||
[K4]: number;
|
||||
~~~~
|
||||
!!! error TS1170: A computed property name in a type literal must refer to an expression whose type is a literal type or a 'unique symbol' type.
|
||||
~~
|
||||
!!! error TS2693: 'K4' only refers to a type, but is being used as a value here.
|
||||
k4: string;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
//// [typeUsedAsTypeLiteralIndex.ts]
|
||||
type K = number | string;
|
||||
type T = {
|
||||
[K]: number; // Did you mean to use 'P in K'?
|
||||
}
|
||||
|
||||
const K1 = Symbol();
|
||||
type T1 = {
|
||||
[K1]: number;
|
||||
}
|
||||
|
||||
type K2 = "x" | "y";
|
||||
type T2 = {
|
||||
[K2]: number; // Did you mean to use 'K in K2'?
|
||||
}
|
||||
|
||||
type K3 = number | string;
|
||||
type T3 = {
|
||||
[K3]: number; // Did you mean to use 'K in K3'?
|
||||
}
|
||||
|
||||
type K4 = number | string;
|
||||
type T4 = {
|
||||
[K4]: number;
|
||||
k4: string;
|
||||
}
|
||||
|
||||
|
||||
//// [typeUsedAsTypeLiteralIndex.js]
|
||||
const K1 = Symbol();
|
||||
@@ -0,0 +1,56 @@
|
||||
=== tests/cases/compiler/typeUsedAsTypeLiteralIndex.ts ===
|
||||
type K = number | string;
|
||||
>K : Symbol(K, Decl(typeUsedAsTypeLiteralIndex.ts, 0, 0))
|
||||
|
||||
type T = {
|
||||
>T : Symbol(T, Decl(typeUsedAsTypeLiteralIndex.ts, 0, 25))
|
||||
|
||||
[K]: number; // Did you mean to use 'P in K'?
|
||||
>[K] : Symbol([K], Decl(typeUsedAsTypeLiteralIndex.ts, 1, 10))
|
||||
}
|
||||
|
||||
const K1 = Symbol();
|
||||
>K1 : Symbol(K1, Decl(typeUsedAsTypeLiteralIndex.ts, 5, 5))
|
||||
>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2019.symbol.d.ts, --, --))
|
||||
|
||||
type T1 = {
|
||||
>T1 : Symbol(T1, Decl(typeUsedAsTypeLiteralIndex.ts, 5, 20))
|
||||
|
||||
[K1]: number;
|
||||
>[K1] : Symbol([K1], Decl(typeUsedAsTypeLiteralIndex.ts, 6, 11))
|
||||
>K1 : Symbol(K1, Decl(typeUsedAsTypeLiteralIndex.ts, 5, 5))
|
||||
}
|
||||
|
||||
type K2 = "x" | "y";
|
||||
>K2 : Symbol(K2, Decl(typeUsedAsTypeLiteralIndex.ts, 8, 1))
|
||||
|
||||
type T2 = {
|
||||
>T2 : Symbol(T2, Decl(typeUsedAsTypeLiteralIndex.ts, 10, 20))
|
||||
|
||||
[K2]: number; // Did you mean to use 'K in K2'?
|
||||
>[K2] : Symbol([K2], Decl(typeUsedAsTypeLiteralIndex.ts, 11, 11))
|
||||
}
|
||||
|
||||
type K3 = number | string;
|
||||
>K3 : Symbol(K3, Decl(typeUsedAsTypeLiteralIndex.ts, 13, 1))
|
||||
|
||||
type T3 = {
|
||||
>T3 : Symbol(T3, Decl(typeUsedAsTypeLiteralIndex.ts, 15, 26))
|
||||
|
||||
[K3]: number; // Did you mean to use 'K in K3'?
|
||||
>[K3] : Symbol([K3], Decl(typeUsedAsTypeLiteralIndex.ts, 16, 11))
|
||||
}
|
||||
|
||||
type K4 = number | string;
|
||||
>K4 : Symbol(K4, Decl(typeUsedAsTypeLiteralIndex.ts, 18, 1))
|
||||
|
||||
type T4 = {
|
||||
>T4 : Symbol(T4, Decl(typeUsedAsTypeLiteralIndex.ts, 20, 26))
|
||||
|
||||
[K4]: number;
|
||||
>[K4] : Symbol([K4], Decl(typeUsedAsTypeLiteralIndex.ts, 21, 11))
|
||||
|
||||
k4: string;
|
||||
>k4 : Symbol(k4, Decl(typeUsedAsTypeLiteralIndex.ts, 22, 17))
|
||||
}
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
=== tests/cases/compiler/typeUsedAsTypeLiteralIndex.ts ===
|
||||
type K = number | string;
|
||||
>K : K
|
||||
|
||||
type T = {
|
||||
>T : T
|
||||
|
||||
[K]: number; // Did you mean to use 'P in K'?
|
||||
>[K] : number
|
||||
>K : any
|
||||
}
|
||||
|
||||
const K1 = Symbol();
|
||||
>K1 : unique symbol
|
||||
>Symbol() : unique symbol
|
||||
>Symbol : SymbolConstructor
|
||||
|
||||
type T1 = {
|
||||
>T1 : T1
|
||||
|
||||
[K1]: number;
|
||||
>[K1] : number
|
||||
>K1 : unique symbol
|
||||
}
|
||||
|
||||
type K2 = "x" | "y";
|
||||
>K2 : K2
|
||||
|
||||
type T2 = {
|
||||
>T2 : T2
|
||||
|
||||
[K2]: number; // Did you mean to use 'K in K2'?
|
||||
>[K2] : number
|
||||
>K2 : any
|
||||
}
|
||||
|
||||
type K3 = number | string;
|
||||
>K3 : K
|
||||
|
||||
type T3 = {
|
||||
>T3 : T3
|
||||
|
||||
[K3]: number; // Did you mean to use 'K in K3'?
|
||||
>[K3] : number
|
||||
>K3 : any
|
||||
}
|
||||
|
||||
type K4 = number | string;
|
||||
>K4 : K
|
||||
|
||||
type T4 = {
|
||||
>T4 : T4
|
||||
|
||||
[K4]: number;
|
||||
>[K4] : number
|
||||
>K4 : any
|
||||
|
||||
k4: string;
|
||||
>k4 : string
|
||||
}
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
// @target: esnext
|
||||
|
||||
type K = number | string;
|
||||
type T = {
|
||||
[K]: number; // Did you mean to use 'P in K'?
|
||||
}
|
||||
|
||||
const K1 = Symbol();
|
||||
type T1 = {
|
||||
[K1]: number;
|
||||
}
|
||||
|
||||
type K2 = "x" | "y";
|
||||
type T2 = {
|
||||
[K2]: number; // Did you mean to use 'K in K2'?
|
||||
}
|
||||
|
||||
type K3 = number | string;
|
||||
type T3 = {
|
||||
[K3]: number; // Did you mean to use 'K in K3'?
|
||||
}
|
||||
|
||||
type K4 = number | string;
|
||||
type T4 = {
|
||||
[K4]: number;
|
||||
k4: string;
|
||||
}
|
||||
Reference in New Issue
Block a user