Skip to content

Commit

Permalink
fix(25770): add diagnostic message for the possible mapped type used …
Browse files Browse the repository at this point in the history
…as an index
  • Loading branch information
a-tarasyuk committed Aug 10, 2020
1 parent 668bbc6 commit ee7fdf3
Show file tree
Hide file tree
Showing 7 changed files with 216 additions and 3 deletions.
18 changes: 15 additions & 3 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2246,16 +2246,28 @@ 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;
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 :
maybeMappedType(errorLocation, symbol) ?
Diagnostics._0_only_refers_to_a_type_but_is_being_used_as_a_value_here_Did_you_mean_to_use_K_in_0 :
Diagnostics._0_only_refers_to_a_type_but_is_being_used_as_a_value_here;
error(errorLocation, message, unescapeLeadingUnderscores(name));
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":
Expand Down
4 changes: 4 additions & 0 deletions src/compiler/diagnosticMessages.json
Original file line number Diff line number Diff line change
Expand Up @@ -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 'K in {0}'?": {
"category": "Error",
"code": 2690
},
"An import path cannot end with a '{0}' extension. Consider importing '{1}' instead.": {
"category": "Error",
"code": 2691
Expand Down
54 changes: 54 additions & 0 deletions tests/baselines/reference/typeUsedAsTypeLiteralIndex.errors.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
tests/cases/compiler/typeUsedAsTypeLiteralIndex.ts(8,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(8,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(11,6): error TS2300: Duplicate identifier 'K3'.
tests/cases/compiler/typeUsedAsTypeLiteralIndex.ts(12,6): error TS2300: Duplicate identifier 'T3'.
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: '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(16,6): error TS2300: Duplicate identifier 'K3'.
tests/cases/compiler/typeUsedAsTypeLiteralIndex.ts(17,6): error TS2300: Duplicate identifier 'T3'.
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 TS2693: 'K3' only refers to a type, but is being used as a value here.


==== tests/cases/compiler/typeUsedAsTypeLiteralIndex.ts (10 errors) ====
const K1 = Symbol();
type T1 = {
[K1]: number;
}

type K2 = "x" | "y";
type T2 = {
[K2]: 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 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;
~~
!!! error TS2300: Duplicate identifier 'K3'.
type T3 = {
~~
!!! error TS2300: Duplicate identifier 'T3'.
[K3]: 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 TS2690: 'K3' only refers to a type, but is being used as a value here. Did you mean to use 'K in K3'?
}

type K3 = number | string;
~~
!!! error TS2300: Duplicate identifier 'K3'.
type T3 = {
~~
!!! error TS2300: Duplicate identifier 'T3'.
[K3]: 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: 'K3' only refers to a type, but is being used as a value here.
k4: string;
}

25 changes: 25 additions & 0 deletions tests/baselines/reference/typeUsedAsTypeLiteralIndex.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
//// [typeUsedAsTypeLiteralIndex.ts]
const K1 = Symbol();
type T1 = {
[K1]: number;
}

type K2 = "x" | "y";
type T2 = {
[K2]: number;
}

type K3 = number | string;
type T3 = {
[K3]: number;
}

type K3 = number | string;
type T3 = {
[K3]: number;
k4: string;
}


//// [typeUsedAsTypeLiteralIndex.js]
const K1 = Symbol();
46 changes: 46 additions & 0 deletions tests/baselines/reference/typeUsedAsTypeLiteralIndex.symbols
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
=== tests/cases/compiler/typeUsedAsTypeLiteralIndex.ts ===
const K1 = Symbol();
>K1 : Symbol(K1, Decl(typeUsedAsTypeLiteralIndex.ts, 0, 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, 0, 20))

[K1]: number;
>[K1] : Symbol([K1], Decl(typeUsedAsTypeLiteralIndex.ts, 1, 11))
>K1 : Symbol(K1, Decl(typeUsedAsTypeLiteralIndex.ts, 0, 5))
}

type K2 = "x" | "y";
>K2 : Symbol(K2, Decl(typeUsedAsTypeLiteralIndex.ts, 3, 1))

type T2 = {
>T2 : Symbol(T2, Decl(typeUsedAsTypeLiteralIndex.ts, 5, 20))

[K2]: number;
>[K2] : Symbol([K2], Decl(typeUsedAsTypeLiteralIndex.ts, 6, 11))
}

type K3 = number | string;
>K3 : Symbol(K3, Decl(typeUsedAsTypeLiteralIndex.ts, 8, 1))

type T3 = {
>T3 : Symbol(T3, Decl(typeUsedAsTypeLiteralIndex.ts, 10, 26))

[K3]: number;
>[K3] : Symbol([K3], 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;
>[K3] : Symbol([K3], Decl(typeUsedAsTypeLiteralIndex.ts, 16, 11))

k4: string;
>k4 : Symbol(k4, Decl(typeUsedAsTypeLiteralIndex.ts, 17, 17))
}

50 changes: 50 additions & 0 deletions tests/baselines/reference/typeUsedAsTypeLiteralIndex.types
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
=== tests/cases/compiler/typeUsedAsTypeLiteralIndex.ts ===
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;
>[K2] : number
>K2 : any
}

type K3 = number | string;
>K3 : K3

type T3 = {
>T3 : T3

[K3]: number;
>[K3] : number
>K3 : any
}

type K3 = number | string;
>K3 : K3

type T3 = {
>T3 : { k4: string; }

[K3]: number;
>[K3] : number
>K3 : any

k4: string;
>k4 : string
}

22 changes: 22 additions & 0 deletions tests/cases/compiler/typeUsedAsTypeLiteralIndex.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// @target: esnext

const K1 = Symbol();
type T1 = {
[K1]: number;
}

type K2 = "x" | "y";
type T2 = {
[K2]: number;
}

type K3 = number | string;
type T3 = {
[K3]: number;
}

type K3 = number | string;
type T3 = {
[K3]: number;
k4: string;
}

0 comments on commit ee7fdf3

Please sign in to comment.