Skip to content

Commit 09ebb70

Browse files
committed
Add extra tests for index signature + address code review feedback.
1 parent 3741ea2 commit 09ebb70

26 files changed

+249
-85
lines changed

src/compiler/checker.ts

Lines changed: 39 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -3215,15 +3215,15 @@ module ts {
32153215
}
32163216

32173217
function getIndexDeclarationOfSymbol(symbol: Symbol, kind: IndexKind): SignatureDeclaration {
3218-
let syntaxKind = kind === IndexKind.Number ? SyntaxKind.NumberKeyword : SyntaxKind.StringKeyword;
3218+
let flagCheck = kind === IndexKind.Number ? TypeFlags.NumberLike : TypeFlags.String;
32193219
let indexSymbol = getIndexSymbol(symbol);
32203220
if (indexSymbol) {
32213221
let len = indexSymbol.declarations.length;
32223222
for (let decl of indexSymbol.declarations) {
32233223
let node = <SignatureDeclaration>decl;
32243224
if (node.parameters.length === 1) {
3225-
let parameter = node.parameters[0];
3226-
if (parameter && parameter.type && parameter.type.kind === syntaxKind) {
3225+
let type = getTypeFromIndexSignatureParameter(node.parameters[0]);
3226+
if(type && (type.flags & flagCheck)) {
32273227
return node;
32283228
}
32293229
}
@@ -8139,24 +8139,27 @@ module ts {
81398139
let seenStringIndexer = false;
81408140
for (let decl of indexSymbol.declarations) {
81418141
let declaration = <SignatureDeclaration>decl;
8142-
if (declaration.parameters.length === 1 && declaration.parameters[0].type) {
8143-
switch (declaration.parameters[0].type.kind) {
8144-
case SyntaxKind.StringKeyword:
8145-
if (!seenStringIndexer) {
8146-
seenStringIndexer = true;
8147-
}
8148-
else {
8149-
error(declaration, Diagnostics.Duplicate_string_index_signature);
8150-
}
8151-
break;
8152-
case SyntaxKind.NumberKeyword:
8153-
if (!seenNumericIndexer) {
8154-
seenNumericIndexer = true;
8155-
}
8156-
else {
8157-
error(declaration, Diagnostics.Duplicate_number_index_signature);
8158-
}
8159-
break;
8142+
if (declaration.parameters.length === 1) {
8143+
let type = getTypeFromIndexSignatureParameter(declaration.parameters[0])
8144+
if (!type) {
8145+
continue;
8146+
}
8147+
8148+
if (type.flags & TypeFlags.String) {
8149+
if (!seenStringIndexer) {
8150+
seenStringIndexer = true;
8151+
}
8152+
else {
8153+
error(declaration, Diagnostics.Duplicate_string_index_signature);
8154+
}
8155+
}
8156+
else if (type.flags & TypeFlags.NumberLike) {
8157+
if (!seenNumericIndexer) {
8158+
seenNumericIndexer = true;
8159+
}
8160+
else {
8161+
error(declaration, Diagnostics.Duplicate_number_index_signature);
8162+
}
81608163
}
81618164
}
81628165
}
@@ -12100,18 +12103,23 @@ module ts {
1210012103
return false;
1210112104
}
1210212105

12103-
function isValidTypeOfIndexSignatureParameter(parameter: ParameterDeclaration): boolean {
12104-
if (parameter.type.kind === SyntaxKind.StringKeyword || parameter.type.kind === SyntaxKind.NumberKeyword) {
12105-
return true;
12106-
}
12106+
function getTypeFromIndexSignatureParameter(parameter: ParameterDeclaration): Type {
12107+
if (parameter.type) {
12108+
if(parameter.type.kind === SyntaxKind.StringKeyword) {
12109+
return stringType;
12110+
}
12111+
if(parameter.type.kind === SyntaxKind.NumberKeyword) {
12112+
return numberType;
12113+
}
1210712114

12108-
if (parameter.type.kind === SyntaxKind.TypeReference) {
12109-
var type = getTypeFromTypeReference(<TypeReferenceNode>(parameter.type));
12110-
if (type.flags & TypeFlags.NumberLike) {
12111-
return true;
12115+
if (parameter.type.kind === SyntaxKind.TypeReference) {
12116+
var type = getTypeFromTypeReference(<TypeReferenceNode>(parameter.type));
12117+
if (type.flags & TypeFlags.NumberLike) {
12118+
return type;
12119+
}
1211212120
}
1211312121
}
12114-
return false;
12122+
return undefined;
1211512123
}
1211612124

1211712125
function checkGrammarIndexSignatureParameters(node: SignatureDeclaration): boolean {
@@ -12139,7 +12147,7 @@ module ts {
1213912147
if (!parameter.type) {
1214012148
return grammarErrorOnNode(parameter.name, Diagnostics.An_index_signature_parameter_must_have_a_type_annotation);
1214112149
}
12142-
if (!isValidTypeOfIndexSignatureParameter(parameter)) {
12150+
if (!getTypeFromIndexSignatureParameter(parameter)) {
1214312151
return grammarErrorOnNode(parameter.name, Diagnostics.An_index_signature_parameter_type_must_be_string_number_or_an_enum_type);
1214412152
}
1214512153
if (!node.type) {

tests/baselines/reference/arraySigChecking.errors.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
tests/cases/compiler/arraySigChecking.ts(11,17): error TS1023: An index signature parameter type must be 'string', 'number' or Enum.
1+
tests/cases/compiler/arraySigChecking.ts(11,17): error TS1023: An index signature parameter type must be 'string', 'number', or an enum type.
22
tests/cases/compiler/arraySigChecking.ts(18,5): error TS2322: Type 'void[]' is not assignable to type 'string[]'.
33
Type 'void' is not assignable to type 'string'.
44
tests/cases/compiler/arraySigChecking.ts(22,1): error TS2322: Type 'number[][]' is not assignable to type 'number[][][]'.
@@ -20,7 +20,7 @@ tests/cases/compiler/arraySigChecking.ts(22,1): error TS2322: Type 'number[][]'
2020

2121
var foo: { [index: any]; }; // expect an error here
2222
~~~~~
23-
!!! error TS1023: An index signature parameter type must be 'string', 'number' or Enum.
23+
!!! error TS1023: An index signature parameter type must be 'string', 'number', or an enum type.
2424
}
2525

2626
interface myInt {

tests/baselines/reference/genericTypeReferenceWithoutTypeArgument.d.errors.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ tests/cases/conformance/types/specifyingTypes/typeReferences/genericTypeReferenc
22
tests/cases/conformance/types/specifyingTypes/typeReferences/genericTypeReferenceWithoutTypeArgument.d.ts(10,21): error TS2314: Generic type 'C<T>' requires 1 type argument(s).
33
tests/cases/conformance/types/specifyingTypes/typeReferences/genericTypeReferenceWithoutTypeArgument.d.ts(11,22): error TS2314: Generic type 'C<T>' requires 1 type argument(s).
44
tests/cases/conformance/types/specifyingTypes/typeReferences/genericTypeReferenceWithoutTypeArgument.d.ts(11,26): error TS2314: Generic type 'C<T>' requires 1 type argument(s).
5-
tests/cases/conformance/types/specifyingTypes/typeReferences/genericTypeReferenceWithoutTypeArgument.d.ts(12,19): error TS1023: An index signature parameter type must be 'string', 'number' or Enum.
5+
tests/cases/conformance/types/specifyingTypes/typeReferences/genericTypeReferenceWithoutTypeArgument.d.ts(12,19): error TS1023: An index signature parameter type must be 'string', 'number', or an enum type.
66
tests/cases/conformance/types/specifyingTypes/typeReferences/genericTypeReferenceWithoutTypeArgument.d.ts(12,22): error TS2314: Generic type 'C<T>' requires 1 type argument(s).
77
tests/cases/conformance/types/specifyingTypes/typeReferences/genericTypeReferenceWithoutTypeArgument.d.ts(12,26): error TS2314: Generic type 'C<T>' requires 1 type argument(s).
88
tests/cases/conformance/types/specifyingTypes/typeReferences/genericTypeReferenceWithoutTypeArgument.d.ts(14,23): error TS2314: Generic type 'C<T>' requires 1 type argument(s).
@@ -36,7 +36,7 @@ tests/cases/conformance/types/specifyingTypes/typeReferences/genericTypeReferenc
3636
!!! error TS2314: Generic type 'C<T>' requires 1 type argument(s).
3737
declare var d: { [x: C]: C };
3838
~
39-
!!! error TS1023: An index signature parameter type must be 'string', 'number' or Enum.
39+
!!! error TS1023: An index signature parameter type must be 'string', 'number', or an enum type.
4040
~
4141
!!! error TS2314: Generic type 'C<T>' requires 1 type argument(s).
4242
~

tests/baselines/reference/genericTypeReferenceWithoutTypeArgument.errors.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ tests/cases/conformance/types/specifyingTypes/typeReferences/genericTypeReferenc
22
tests/cases/conformance/types/specifyingTypes/typeReferences/genericTypeReferenceWithoutTypeArgument.ts(10,13): error TS2314: Generic type 'C<T>' requires 1 type argument(s).
33
tests/cases/conformance/types/specifyingTypes/typeReferences/genericTypeReferenceWithoutTypeArgument.ts(11,14): error TS2314: Generic type 'C<T>' requires 1 type argument(s).
44
tests/cases/conformance/types/specifyingTypes/typeReferences/genericTypeReferenceWithoutTypeArgument.ts(11,18): error TS2314: Generic type 'C<T>' requires 1 type argument(s).
5-
tests/cases/conformance/types/specifyingTypes/typeReferences/genericTypeReferenceWithoutTypeArgument.ts(12,11): error TS1023: An index signature parameter type must be 'string', 'number' or Enum.
5+
tests/cases/conformance/types/specifyingTypes/typeReferences/genericTypeReferenceWithoutTypeArgument.ts(12,11): error TS1023: An index signature parameter type must be 'string', 'number', or an enum type.
66
tests/cases/conformance/types/specifyingTypes/typeReferences/genericTypeReferenceWithoutTypeArgument.ts(12,14): error TS2314: Generic type 'C<T>' requires 1 type argument(s).
77
tests/cases/conformance/types/specifyingTypes/typeReferences/genericTypeReferenceWithoutTypeArgument.ts(12,18): error TS2314: Generic type 'C<T>' requires 1 type argument(s).
88
tests/cases/conformance/types/specifyingTypes/typeReferences/genericTypeReferenceWithoutTypeArgument.ts(14,13): error TS2314: Generic type 'C<T>' requires 1 type argument(s).
@@ -46,7 +46,7 @@ tests/cases/conformance/types/specifyingTypes/typeReferences/genericTypeReferenc
4646
!!! error TS2314: Generic type 'C<T>' requires 1 type argument(s).
4747
var d: { [x: C]: C };
4848
~
49-
!!! error TS1023: An index signature parameter type must be 'string', 'number' or Enum.
49+
!!! error TS1023: An index signature parameter type must be 'string', 'number', or an enum type.
5050
~
5151
!!! error TS2314: Generic type 'C<T>' requires 1 type argument(s).
5252
~

tests/baselines/reference/genericTypeReferenceWithoutTypeArgument2.errors.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ tests/cases/conformance/types/specifyingTypes/typeReferences/genericTypeReferenc
22
tests/cases/conformance/types/specifyingTypes/typeReferences/genericTypeReferenceWithoutTypeArgument2.ts(10,13): error TS2314: Generic type 'I<T>' requires 1 type argument(s).
33
tests/cases/conformance/types/specifyingTypes/typeReferences/genericTypeReferenceWithoutTypeArgument2.ts(11,14): error TS2314: Generic type 'I<T>' requires 1 type argument(s).
44
tests/cases/conformance/types/specifyingTypes/typeReferences/genericTypeReferenceWithoutTypeArgument2.ts(11,18): error TS2314: Generic type 'I<T>' requires 1 type argument(s).
5-
tests/cases/conformance/types/specifyingTypes/typeReferences/genericTypeReferenceWithoutTypeArgument2.ts(12,11): error TS1023: An index signature parameter type must be 'string', 'number' or Enum.
5+
tests/cases/conformance/types/specifyingTypes/typeReferences/genericTypeReferenceWithoutTypeArgument2.ts(12,11): error TS1023: An index signature parameter type must be 'string', 'number', or an enum type.
66
tests/cases/conformance/types/specifyingTypes/typeReferences/genericTypeReferenceWithoutTypeArgument2.ts(12,14): error TS2314: Generic type 'I<T>' requires 1 type argument(s).
77
tests/cases/conformance/types/specifyingTypes/typeReferences/genericTypeReferenceWithoutTypeArgument2.ts(12,18): error TS2314: Generic type 'I<T>' requires 1 type argument(s).
88
tests/cases/conformance/types/specifyingTypes/typeReferences/genericTypeReferenceWithoutTypeArgument2.ts(14,13): error TS2314: Generic type 'I<T>' requires 1 type argument(s).
@@ -46,7 +46,7 @@ tests/cases/conformance/types/specifyingTypes/typeReferences/genericTypeReferenc
4646
!!! error TS2314: Generic type 'I<T>' requires 1 type argument(s).
4747
var d: { [x: I]: I };
4848
~
49-
!!! error TS1023: An index signature parameter type must be 'string', 'number' or Enum.
49+
!!! error TS1023: An index signature parameter type must be 'string', 'number', or an enum type.
5050
~
5151
!!! error TS2314: Generic type 'I<T>' requires 1 type argument(s).
5252
~

tests/baselines/reference/genericTypeReferenceWithoutTypeArgument3.errors.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ tests/cases/conformance/types/specifyingTypes/typeReferences/genericTypeReferenc
22
tests/cases/conformance/types/specifyingTypes/typeReferences/genericTypeReferenceWithoutTypeArgument3.ts(10,21): error TS2314: Generic type 'C<T>' requires 1 type argument(s).
33
tests/cases/conformance/types/specifyingTypes/typeReferences/genericTypeReferenceWithoutTypeArgument3.ts(11,22): error TS2314: Generic type 'C<T>' requires 1 type argument(s).
44
tests/cases/conformance/types/specifyingTypes/typeReferences/genericTypeReferenceWithoutTypeArgument3.ts(11,26): error TS2314: Generic type 'C<T>' requires 1 type argument(s).
5-
tests/cases/conformance/types/specifyingTypes/typeReferences/genericTypeReferenceWithoutTypeArgument3.ts(12,19): error TS1023: An index signature parameter type must be 'string', 'number' or Enum.
5+
tests/cases/conformance/types/specifyingTypes/typeReferences/genericTypeReferenceWithoutTypeArgument3.ts(12,19): error TS1023: An index signature parameter type must be 'string', 'number', or an enum type.
66
tests/cases/conformance/types/specifyingTypes/typeReferences/genericTypeReferenceWithoutTypeArgument3.ts(12,22): error TS2314: Generic type 'C<T>' requires 1 type argument(s).
77
tests/cases/conformance/types/specifyingTypes/typeReferences/genericTypeReferenceWithoutTypeArgument3.ts(12,26): error TS2314: Generic type 'C<T>' requires 1 type argument(s).
88
tests/cases/conformance/types/specifyingTypes/typeReferences/genericTypeReferenceWithoutTypeArgument3.ts(14,23): error TS2314: Generic type 'C<T>' requires 1 type argument(s).
@@ -36,7 +36,7 @@ tests/cases/conformance/types/specifyingTypes/typeReferences/genericTypeReferenc
3636
!!! error TS2314: Generic type 'C<T>' requires 1 type argument(s).
3737
declare var d: { [x: C]: C };
3838
~
39-
!!! error TS1023: An index signature parameter type must be 'string', 'number' or Enum.
39+
!!! error TS1023: An index signature parameter type must be 'string', 'number', or an enum type.
4040
~
4141
!!! error TS2314: Generic type 'C<T>' requires 1 type argument(s).
4242
~

tests/baselines/reference/indexSignatureTypeCheck.errors.txt

Lines changed: 77 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,26 @@
1-
tests/cases/compiler/indexSignatureTypeCheck.ts(34,1): error TS2342: An index expression argument must be of type 'string', 'number', 'symbol, or 'any'.
2-
tests/cases/compiler/indexSignatureTypeCheck.ts(37,8): error TS1019: An index signature parameter cannot have a question mark.
3-
tests/cases/compiler/indexSignatureTypeCheck.ts(38,6): error TS1017: An index signature cannot have a rest parameter.
4-
tests/cases/compiler/indexSignatureTypeCheck.ts(39,6): error TS1096: An index signature must have exactly one parameter.
1+
tests/cases/compiler/indexSignatureTypeCheck.ts(35,1): error TS2342: An index expression argument must be of type 'string', 'number', 'symbol, or 'any'.
2+
tests/cases/compiler/indexSignatureTypeCheck.ts(38,8): error TS1019: An index signature parameter cannot have a question mark.
3+
tests/cases/compiler/indexSignatureTypeCheck.ts(39,6): error TS1017: An index signature cannot have a rest parameter.
54
tests/cases/compiler/indexSignatureTypeCheck.ts(40,6): error TS1096: An index signature must have exactly one parameter.
5+
tests/cases/compiler/indexSignatureTypeCheck.ts(41,6): error TS1096: An index signature must have exactly one parameter.
6+
tests/cases/compiler/indexSignatureTypeCheck.ts(51,2): error TS2375: Duplicate number index signature.
7+
tests/cases/compiler/indexSignatureTypeCheck.ts(56,2): error TS2375: Duplicate number index signature.
8+
tests/cases/compiler/indexSignatureTypeCheck.ts(64,1): error TS2322: Type '{ [x: number]: string; }' is not assignable to type '{ [x: string]: string; }'.
9+
Index signature is missing in type '{ [x: number]: string; }'.
10+
tests/cases/compiler/indexSignatureTypeCheck.ts(65,1): error TS2322: Type '{ [x: number]: number; }' is not assignable to type '{ [x: string]: string; }'.
11+
Index signature is missing in type '{ [x: number]: number; }'.
12+
tests/cases/compiler/indexSignatureTypeCheck.ts(69,1): error TS2322: Type '{ [x: number]: number; }' is not assignable to type '{ [x: number]: string; }'.
13+
Index signatures are incompatible.
14+
Type 'number' is not assignable to type 'string'.
15+
tests/cases/compiler/indexSignatureTypeCheck.ts(71,1): error TS2322: Type '{ [x: string]: string; }' is not assignable to type '{ [x: number]: number; }'.
16+
Index signatures are incompatible.
17+
Type 'string' is not assignable to type 'number'.
18+
tests/cases/compiler/indexSignatureTypeCheck.ts(72,1): error TS2322: Type '{ [x: number]: string; }' is not assignable to type '{ [x: number]: number; }'.
19+
Index signatures are incompatible.
20+
Type 'string' is not assignable to type 'number'.
621

722

8-
==== tests/cases/compiler/indexSignatureTypeCheck.ts (5 errors) ====
23+
==== tests/cases/compiler/indexSignatureTypeCheck.ts (12 errors) ====
924
interface IPropertySet {
1025
[index: string]: any;
1126
}
@@ -26,6 +41,7 @@ tests/cases/compiler/indexSignatureTypeCheck.ts(40,6): error TS1096: An index si
2641
[index: Val]: Val;
2742
}
2843

44+
2945
interface IEnum2 {
3046
[index: Val2]: Val2;
3147
}
@@ -56,4 +72,59 @@ tests/cases/compiler/indexSignatureTypeCheck.ts(40,6): error TS1096: An index si
5672
[p6: string, ...p7: any[]];
5773
~~
5874
!!! error TS1096: An index signature must have exactly one parameter.
59-
}
75+
}
76+
77+
enum E {
78+
A, B, C
79+
}
80+
81+
82+
interface DuplicateAccess {
83+
[index: Val]: Val;
84+
[index: Val2]: Val2;
85+
~~~~~~~~~~~~~~~~~~~~
86+
!!! error TS2375: Duplicate number index signature.
87+
}
88+
89+
interface DuplicateAccess2 {
90+
[index: number]: Val;
91+
[index: Val3]: Val3;
92+
~~~~~~~~~~~~~~~~~~~~
93+
!!! error TS2375: Duplicate number index signature.
94+
}
95+
96+
var x: { [x: string]: string }
97+
var y: { [x: number]: string }
98+
var z: { [x: E]: number }
99+
100+
x = x;
101+
x = y;
102+
~
103+
!!! error TS2322: Type '{ [x: number]: string; }' is not assignable to type '{ [x: string]: string; }'.
104+
!!! error TS2322: Index signature is missing in type '{ [x: number]: string; }'.
105+
x = z;
106+
~
107+
!!! error TS2322: Type '{ [x: number]: number; }' is not assignable to type '{ [x: string]: string; }'.
108+
!!! error TS2322: Index signature is missing in type '{ [x: number]: number; }'.
109+
110+
y = x;
111+
y = y;
112+
y = z;
113+
~
114+
!!! error TS2322: Type '{ [x: number]: number; }' is not assignable to type '{ [x: number]: string; }'.
115+
!!! error TS2322: Index signatures are incompatible.
116+
!!! error TS2322: Type 'number' is not assignable to type 'string'.
117+
118+
z = x;
119+
~
120+
!!! error TS2322: Type '{ [x: string]: string; }' is not assignable to type '{ [x: number]: number; }'.
121+
!!! error TS2322: Index signatures are incompatible.
122+
!!! error TS2322: Type 'string' is not assignable to type 'number'.
123+
z = y;
124+
~
125+
!!! error TS2322: Type '{ [x: number]: string; }' is not assignable to type '{ [x: number]: number; }'.
126+
!!! error TS2322: Index signatures are incompatible.
127+
!!! error TS2322: Type 'string' is not assignable to type 'number'.
128+
z = z;
129+
130+

0 commit comments

Comments
 (0)