From 0c089d8d666b7e0540069b51fd9966c32e279b0f Mon Sep 17 00:00:00 2001 From: kujon Date: Fri, 15 Dec 2017 21:25:16 +0000 Subject: [PATCH] Better error messages for aliased index types --- src/compiler/checker.ts | 6 +++ src/compiler/diagnosticMessages.json | 4 ++ .../reference/indexerConstraints2.errors.txt | 30 ++++++++++++++- .../reference/indexerConstraints2.js | 19 ++++++++++ .../reference/indexerConstraints2.symbols | 37 +++++++++++++++++++ .../reference/indexerConstraints2.types | 37 +++++++++++++++++++ tests/cases/compiler/indexerConstraints2.ts | 19 ++++++++++ 7 files changed, 151 insertions(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index ca73d92e0c0..a2e0c490642 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -25775,6 +25775,12 @@ namespace ts { return grammarErrorOnNode(parameter.name, Diagnostics.An_index_signature_parameter_must_have_a_type_annotation); } if (parameter.type.kind !== SyntaxKind.StringKeyword && parameter.type.kind !== SyntaxKind.NumberKeyword) { + const type = getTypeFromTypeNode(parameter.type); + + if (type.flags & TypeFlags.String || type.flags & TypeFlags.Number) { + return grammarErrorOnNode(parameter.name, Diagnostics.An_index_signature_parameter_type_cannot_be_a_type_alias_Use_index_Colon_0_instead, typeToString(type)); + } + return grammarErrorOnNode(parameter.name, Diagnostics.An_index_signature_parameter_type_must_be_string_or_number); } if (!node.type) { diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 336def7ea52..083396e51d2 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -939,6 +939,10 @@ "category": "Error", "code": 1335 }, + "An index signature parameter type cannot be a type alias. Use '[index: {0}]' instead.": { + "category": "Error", + "code": 1336 + }, "Duplicate identifier '{0}'.": { "category": "Error", diff --git a/tests/baselines/reference/indexerConstraints2.errors.txt b/tests/baselines/reference/indexerConstraints2.errors.txt index 316486e709f..7e13c2ba399 100644 --- a/tests/baselines/reference/indexerConstraints2.errors.txt +++ b/tests/baselines/reference/indexerConstraints2.errors.txt @@ -1,9 +1,12 @@ tests/cases/compiler/indexerConstraints2.ts(9,5): error TS2413: Numeric index type 'A' is not assignable to string index type 'B'. tests/cases/compiler/indexerConstraints2.ts(17,5): error TS2413: Numeric index type 'A' is not assignable to string index type 'B'. tests/cases/compiler/indexerConstraints2.ts(26,5): error TS2413: Numeric index type 'A' is not assignable to string index type 'B'. +tests/cases/compiler/indexerConstraints2.ts(34,6): error TS1336: An index signature parameter type cannot be a type alias. Use '[index: number]' instead. +tests/cases/compiler/indexerConstraints2.ts(40,6): error TS1336: An index signature parameter type cannot be a type alias. Use '[index: string]' instead. +tests/cases/compiler/indexerConstraints2.ts(46,6): error TS1023: An index signature parameter type must be 'string' or 'number'. -==== tests/cases/compiler/indexerConstraints2.ts (3 errors) ==== +==== tests/cases/compiler/indexerConstraints2.ts (6 errors) ==== class A { a: number; } class B extends A { b: number; } @@ -37,4 +40,29 @@ tests/cases/compiler/indexerConstraints2.ts(26,5): error TS2413: Numeric index t ~~~~~~~~~~~~~~~ !!! error TS2413: Numeric index type 'A' is not assignable to string index type 'B'. [s: string]: B; + } + + + type AliasedNumber = number; + + interface L { + [n: AliasedNumber]: A; + ~ +!!! error TS1336: An index signature parameter type cannot be a type alias. Use '[index: number]' instead. + } + + type AliasedString = string; + + interface M { + [s: AliasedString]: A; + ~ +!!! error TS1336: An index signature parameter type cannot be a type alias. Use '[index: string]' instead. + } + + type AliasedBoolean = boolean; + + interface N { + [b: AliasedBoolean]: A; + ~ +!!! error TS1023: An index signature parameter type must be 'string' or 'number'. } \ No newline at end of file diff --git a/tests/baselines/reference/indexerConstraints2.js b/tests/baselines/reference/indexerConstraints2.js index f5bfc3c64d8..56da818e37d 100644 --- a/tests/baselines/reference/indexerConstraints2.js +++ b/tests/baselines/reference/indexerConstraints2.js @@ -26,6 +26,25 @@ class J { class K extends J { [n: number]: A; [s: string]: B; +} + + +type AliasedNumber = number; + +interface L { + [n: AliasedNumber]: A; +} + +type AliasedString = string; + +interface M { + [s: AliasedString]: A; +} + +type AliasedBoolean = boolean; + +interface N { + [b: AliasedBoolean]: A; } //// [indexerConstraints2.js] diff --git a/tests/baselines/reference/indexerConstraints2.symbols b/tests/baselines/reference/indexerConstraints2.symbols index de606a2c2e4..96f2b84127e 100644 --- a/tests/baselines/reference/indexerConstraints2.symbols +++ b/tests/baselines/reference/indexerConstraints2.symbols @@ -62,3 +62,40 @@ class K extends J { >s : Symbol(s, Decl(indexerConstraints2.ts, 26, 5)) >B : Symbol(B, Decl(indexerConstraints2.ts, 0, 22)) } + + +type AliasedNumber = number; +>AliasedNumber : Symbol(AliasedNumber, Decl(indexerConstraints2.ts, 27, 1)) + +interface L { +>L : Symbol(L, Decl(indexerConstraints2.ts, 30, 28)) + + [n: AliasedNumber]: A; +>n : Symbol(n, Decl(indexerConstraints2.ts, 33, 5)) +>AliasedNumber : Symbol(AliasedNumber, Decl(indexerConstraints2.ts, 27, 1)) +>A : Symbol(A, Decl(indexerConstraints2.ts, 0, 0)) +} + +type AliasedString = string; +>AliasedString : Symbol(AliasedString, Decl(indexerConstraints2.ts, 34, 1)) + +interface M { +>M : Symbol(M, Decl(indexerConstraints2.ts, 36, 28)) + + [s: AliasedString]: A; +>s : Symbol(s, Decl(indexerConstraints2.ts, 39, 5)) +>AliasedString : Symbol(AliasedString, Decl(indexerConstraints2.ts, 34, 1)) +>A : Symbol(A, Decl(indexerConstraints2.ts, 0, 0)) +} + +type AliasedBoolean = boolean; +>AliasedBoolean : Symbol(AliasedBoolean, Decl(indexerConstraints2.ts, 40, 1)) + +interface N { +>N : Symbol(N, Decl(indexerConstraints2.ts, 42, 30)) + + [b: AliasedBoolean]: A; +>b : Symbol(b, Decl(indexerConstraints2.ts, 45, 5)) +>AliasedBoolean : Symbol(AliasedBoolean, Decl(indexerConstraints2.ts, 40, 1)) +>A : Symbol(A, Decl(indexerConstraints2.ts, 0, 0)) +} diff --git a/tests/baselines/reference/indexerConstraints2.types b/tests/baselines/reference/indexerConstraints2.types index 2a52f0e41db..29fb2526e84 100644 --- a/tests/baselines/reference/indexerConstraints2.types +++ b/tests/baselines/reference/indexerConstraints2.types @@ -62,3 +62,40 @@ class K extends J { >s : string >B : B } + + +type AliasedNumber = number; +>AliasedNumber : number + +interface L { +>L : L + + [n: AliasedNumber]: A; +>n : number +>AliasedNumber : number +>A : A +} + +type AliasedString = string; +>AliasedString : string + +interface M { +>M : M + + [s: AliasedString]: A; +>s : string +>AliasedString : string +>A : A +} + +type AliasedBoolean = boolean; +>AliasedBoolean : boolean + +interface N { +>N : N + + [b: AliasedBoolean]: A; +>b : boolean +>AliasedBoolean : boolean +>A : A +} diff --git a/tests/cases/compiler/indexerConstraints2.ts b/tests/cases/compiler/indexerConstraints2.ts index a7439b018e7..9a2e21cc4a1 100644 --- a/tests/cases/compiler/indexerConstraints2.ts +++ b/tests/cases/compiler/indexerConstraints2.ts @@ -25,4 +25,23 @@ class J { class K extends J { [n: number]: A; [s: string]: B; +} + + +type AliasedNumber = number; + +interface L { + [n: AliasedNumber]: A; +} + +type AliasedString = string; + +interface M { + [s: AliasedString]: A; +} + +type AliasedBoolean = boolean; + +interface N { + [b: AliasedBoolean]: A; } \ No newline at end of file