Skip to content

Commit 13b5fe0

Browse files
Ensure that numeric names are in their printed form.
1 parent 5a49bb6 commit 13b5fe0

6 files changed

+173
-101
lines changed

src/compiler/checker.ts

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4094,17 +4094,25 @@ module ts {
40944094

40954095
var numericScanner: Scanner;
40964096
function isNumericName(name: string) {
4097+
// First see if the name is in canonical string representation.
4098+
// Unfortunately this permits various forms of "NaN" and "Infinity",
4099+
// but it is a good check to save time.
4100+
if ((+name).toString() !== name) {
4101+
return false;
4102+
}
4103+
40974104
numericScanner = numericScanner || createScanner(compilerOptions.target || ScriptTarget.ES5, /*skipTrivia*/ false);
40984105
numericScanner.setText(name);
40994106

41004107
// Ensure that the name is nothing more than an optional sign (+/-) and a numeric literal
41014108
// (i.e. it is preceded by nothing and scanning leaves us at the very end of the string).
41024109
var token = numericScanner.scan();
41034110

4104-
if (token === SyntaxKind.MinusToken || token === SyntaxKind.PlusToken) {
4111+
// '+' will never be in front of a number in its printed form.
4112+
if (token === SyntaxKind.MinusToken) {
41054113
token = numericScanner.scan();
41064114
}
4107-
4115+
41084116
return token === SyntaxKind.NumericLiteral && numericScanner.getTextPos() === name.length;
41094117
}
41104118

@@ -4158,7 +4166,9 @@ module ts {
41584166
if (hasProperty(properties, id)) {
41594167
if (kind === IndexKind.String || isNumericName(id)) {
41604168
var type = getTypeOfSymbol(properties[id]);
4161-
if (!contains(propTypes, type)) propTypes.push(type);
4169+
if (!contains(propTypes, type)) {
4170+
propTypes.push(type);
4171+
}
41624172
}
41634173
}
41644174
}

tests/baselines/reference/numericIndexerConstrainsPropertyDeclarations.errors.txt

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,16 @@ tests/cases/conformance/types/objectTypeLiteral/indexSignatures/numericIndexerCo
44
tests/cases/conformance/types/objectTypeLiteral/indexSignatures/numericIndexerConstrainsPropertyDeclarations.ts(90,9): error TS1056: Accessors are only available when targeting ECMAScript 5 and higher.
55
tests/cases/conformance/types/objectTypeLiteral/indexSignatures/numericIndexerConstrainsPropertyDeclarations.ts(93,9): error TS1056: Accessors are only available when targeting ECMAScript 5 and higher.
66
tests/cases/conformance/types/objectTypeLiteral/indexSignatures/numericIndexerConstrainsPropertyDeclarations.ts(18,5): error TS2412: Property '2.0' of type 'number' is not assignable to numeric index type 'string'.
7-
tests/cases/conformance/types/objectTypeLiteral/indexSignatures/numericIndexerConstrainsPropertyDeclarations.ts(20,5): error TS2412: Property '"4.0"' of type 'number' is not assignable to numeric index type 'string'.
87
tests/cases/conformance/types/objectTypeLiteral/indexSignatures/numericIndexerConstrainsPropertyDeclarations.ts(21,5): error TS2412: Property '3.0' of type 'MyNumber' is not assignable to numeric index type 'string'.
98
tests/cases/conformance/types/objectTypeLiteral/indexSignatures/numericIndexerConstrainsPropertyDeclarations.ts(50,5): error TS2412: Property '2.0' of type 'number' is not assignable to numeric index type 'string'.
10-
tests/cases/conformance/types/objectTypeLiteral/indexSignatures/numericIndexerConstrainsPropertyDeclarations.ts(55,5): error TS2412: Property '"4.0"' of type 'number' is not assignable to numeric index type 'string'.
119
tests/cases/conformance/types/objectTypeLiteral/indexSignatures/numericIndexerConstrainsPropertyDeclarations.ts(68,5): error TS2412: Property '2.0' of type 'number' is not assignable to numeric index type 'string'.
12-
tests/cases/conformance/types/objectTypeLiteral/indexSignatures/numericIndexerConstrainsPropertyDeclarations.ts(73,5): error TS2412: Property '"4.0"' of type 'number' is not assignable to numeric index type 'string'.
1310
tests/cases/conformance/types/objectTypeLiteral/indexSignatures/numericIndexerConstrainsPropertyDeclarations.ts(78,5): error TS2322: Type '{ [x: number]: {}; 1.0: string; 2.0: number; a: string; b: number; c: () => void; "d": string; "e": number; "3.0": string; "4.0": number; f: unknown; X: string; foo: () => string; }' is not assignable to type '{ [x: number]: string; }':
1411
Index signatures are incompatible:
1512
Type '{}' is not assignable to type 'string'.
1613
tests/cases/conformance/types/objectTypeLiteral/indexSignatures/numericIndexerConstrainsPropertyDeclarations.ts(88,9): error TS2304: Cannot find name 'Myn'.
1714

1815

19-
==== tests/cases/conformance/types/objectTypeLiteral/indexSignatures/numericIndexerConstrainsPropertyDeclarations.ts (14 errors) ====
16+
==== tests/cases/conformance/types/objectTypeLiteral/indexSignatures/numericIndexerConstrainsPropertyDeclarations.ts (11 errors) ====
2017
// String indexer types constrain the types of named properties in their containing type
2118

2219
interface MyNumber extends Number {
@@ -39,8 +36,6 @@ tests/cases/conformance/types/objectTypeLiteral/indexSignatures/numericIndexerCo
3936
!!! error TS2412: Property '2.0' of type 'number' is not assignable to numeric index type 'string'.
4037
"3.0": string; // ok
4138
"4.0": number; // error
42-
~~~~~~~~~~~~~~
43-
!!! error TS2412: Property '"4.0"' of type 'number' is not assignable to numeric index type 'string'.
4439
3.0: MyNumber // error
4540
~~~~~~~~~~~~~
4641
!!! error TS2412: Property '3.0' of type 'MyNumber' is not assignable to numeric index type 'string'.
@@ -86,8 +81,6 @@ tests/cases/conformance/types/objectTypeLiteral/indexSignatures/numericIndexerCo
8681
foo(): string; // ok
8782
"3.0": string; // ok
8883
"4.0": number; // error
89-
~~~~~~~~~~~~~~
90-
!!! error TS2412: Property '"4.0"' of type 'number' is not assignable to numeric index type 'string'.
9184
f: MyNumber; // error
9285
}
9386

@@ -108,8 +101,6 @@ tests/cases/conformance/types/objectTypeLiteral/indexSignatures/numericIndexerCo
108101
foo(): string; // ok
109102
"3.0": string; // ok
110103
"4.0": number; // error
111-
~~~~~~~~~~~~~~
112-
!!! error TS2412: Property '"4.0"' of type 'number' is not assignable to numeric index type 'string'.
113104
f: MyNumber; // error
114105
}
115106

tests/baselines/reference/numericIndexerConstrainsPropertyDeclarations2.errors.txt

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,13 @@
11
tests/cases/conformance/types/objectTypeLiteral/indexSignatures/numericIndexerConstrainsPropertyDeclarations2.ts(16,5): error TS2412: Property '3.0' of type 'number' is not assignable to numeric index type 'A'.
2-
tests/cases/conformance/types/objectTypeLiteral/indexSignatures/numericIndexerConstrainsPropertyDeclarations2.ts(17,5): error TS2412: Property '"4.0"' of type 'string' is not assignable to numeric index type 'A'.
32
tests/cases/conformance/types/objectTypeLiteral/indexSignatures/numericIndexerConstrainsPropertyDeclarations2.ts(25,5): error TS2412: Property '3.0' of type 'number' is not assignable to numeric index type 'A'.
4-
tests/cases/conformance/types/objectTypeLiteral/indexSignatures/numericIndexerConstrainsPropertyDeclarations2.ts(26,5): error TS2412: Property '"4.0"' of type 'string' is not assignable to numeric index type 'A'.
53
tests/cases/conformance/types/objectTypeLiteral/indexSignatures/numericIndexerConstrainsPropertyDeclarations2.ts(34,5): error TS2412: Property '3.0' of type 'number' is not assignable to numeric index type 'A'.
6-
tests/cases/conformance/types/objectTypeLiteral/indexSignatures/numericIndexerConstrainsPropertyDeclarations2.ts(35,5): error TS2412: Property '"4.0"' of type 'string' is not assignable to numeric index type 'A'.
74
tests/cases/conformance/types/objectTypeLiteral/indexSignatures/numericIndexerConstrainsPropertyDeclarations2.ts(39,5): error TS2322: Type '{ [x: number]: {}; 1.0: A; 2.0: B; 3.0: number; "2.5": B; "4.0": string; }' is not assignable to type '{ [x: number]: A; }':
85
Index signatures are incompatible:
96
Type '{}' is not assignable to type 'A':
107
Property 'foo' is missing in type '{}'.
118

129

13-
==== tests/cases/conformance/types/objectTypeLiteral/indexSignatures/numericIndexerConstrainsPropertyDeclarations2.ts (7 errors) ====
10+
==== tests/cases/conformance/types/objectTypeLiteral/indexSignatures/numericIndexerConstrainsPropertyDeclarations2.ts (4 errors) ====
1411
// String indexer providing a constraint of a user defined type
1512

1613
class A {
@@ -30,8 +27,6 @@ tests/cases/conformance/types/objectTypeLiteral/indexSignatures/numericIndexerCo
3027
~~~~~~~~~~~~
3128
!!! error TS2412: Property '3.0' of type 'number' is not assignable to numeric index type 'A'.
3229
"4.0": string; // error
33-
~~~~~~~~~~~~~~
34-
!!! error TS2412: Property '"4.0"' of type 'string' is not assignable to numeric index type 'A'.
3530
}
3631

3732
interface Foo2 {
@@ -43,8 +38,6 @@ tests/cases/conformance/types/objectTypeLiteral/indexSignatures/numericIndexerCo
4338
~~~~~~~~~~~~
4439
!!! error TS2412: Property '3.0' of type 'number' is not assignable to numeric index type 'A'.
4540
"4.0": string; // error
46-
~~~~~~~~~~~~~~
47-
!!! error TS2412: Property '"4.0"' of type 'string' is not assignable to numeric index type 'A'.
4841
}
4942

5043
var a: {
@@ -56,8 +49,6 @@ tests/cases/conformance/types/objectTypeLiteral/indexSignatures/numericIndexerCo
5649
~~~~~~~~~~~~
5750
!!! error TS2412: Property '3.0' of type 'number' is not assignable to numeric index type 'A'.
5851
"4.0": string; // error
59-
~~~~~~~~~~~~~~
60-
!!! error TS2412: Property '"4.0"' of type 'string' is not assignable to numeric index type 'A'.
6152
};
6253

6354
// error
Lines changed: 53 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,54 @@
1-
tests/cases/compiler/propertiesAndIndexersForNumericNames.ts(3,3): error TS2412: Property '"1"' of type 'string' is not assignable to numeric index type 'number'.
2-
tests/cases/compiler/propertiesAndIndexersForNumericNames.ts(4,3): error TS2412: Property '"-1"' of type 'string' is not assignable to numeric index type 'number'.
3-
tests/cases/compiler/propertiesAndIndexersForNumericNames.ts(5,3): error TS2412: Property '"+1"' of type 'string' is not assignable to numeric index type 'number'.
4-
5-
6-
==== tests/cases/compiler/propertiesAndIndexersForNumericNames.ts (3 errors) ====
7-
class C {
8-
[i: number]: number;
9-
public "1": string = "number"; // Error
10-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
11-
!!! error TS2412: Property '"1"' of type 'string' is not assignable to numeric index type 'number'.
12-
public "-1": string = "negative number"; // Error
13-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
14-
!!! error TS2412: Property '"-1"' of type 'string' is not assignable to numeric index type 'number'.
15-
public "+1": string = "positive number (for the paranoid)"; // Error
16-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
17-
!!! error TS2412: Property '"+1"' of type 'string' is not assignable to numeric index type 'number'.
18-
19-
public " 1": string = "leading space"; // No error
20-
public "1 ": string = "trailing space"; // No error
21-
public "": string = "no nothing"; // No error
22-
public " ": string = "just space"; // No error
23-
public "1 0 1": string = "several numbers and spaces"; // No error
24-
public "NaN": string = "not a number"; // No error
25-
public "-NaN": string = "not a negative number"; // No error
26-
public "+Infinity": string = "A gillion"; // No error
27-
public "-Infinity": string = "Negative-a-gillion"; // No error
28-
}
1+
tests/cases/compiler/propertiesAndIndexersForNumericNames.ts(6,5): error TS2412: Property '"1"' of type 'string' is not assignable to numeric index type 'number'.
2+
tests/cases/compiler/propertiesAndIndexersForNumericNames.ts(7,5): error TS2412: Property '"-1"' of type 'string' is not assignable to numeric index type 'number'.
3+
tests/cases/compiler/propertiesAndIndexersForNumericNames.ts(8,5): error TS2412: Property '"-2.5"' of type 'string' is not assignable to numeric index type 'number'.
4+
tests/cases/compiler/propertiesAndIndexersForNumericNames.ts(9,5): error TS2412: Property '"3.141592"' of type 'string' is not assignable to numeric index type 'number'.
5+
tests/cases/compiler/propertiesAndIndexersForNumericNames.ts(10,5): error TS2412: Property '"1.2e-20"' of type 'string' is not assignable to numeric index type 'number'.
6+
7+
8+
==== tests/cases/compiler/propertiesAndIndexersForNumericNames.ts (5 errors) ====
9+
class C {
10+
[i: number]: number;
11+
12+
// These all have numeric names; they should error
13+
// because their types are not compatible with the numeric indexer.
14+
public "1": string = "number"; // Error
15+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
16+
!!! error TS2412: Property '"1"' of type 'string' is not assignable to numeric index type 'number'.
17+
public "-1": string = "negative number"; // Error
18+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
19+
!!! error TS2412: Property '"-1"' of type 'string' is not assignable to numeric index type 'number'.
20+
public "-2.5": string = "negative number"; // Error
21+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
22+
!!! error TS2412: Property '"-2.5"' of type 'string' is not assignable to numeric index type 'number'.
23+
public "3.141592": string = "pi-sitive number"; // Error
24+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
25+
!!! error TS2412: Property '"3.141592"' of type 'string' is not assignable to numeric index type 'number'.
26+
public "1.2e-20": string = "really small number"; // Error
27+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
28+
!!! error TS2412: Property '"1.2e-20"' of type 'string' is not assignable to numeric index type 'number'.
29+
30+
// These all have *partially* numeric names,
31+
// but should really be treated as plain string literals.
32+
public " 1": string = "leading space"; // No error
33+
public "1 ": string = "trailing space"; // No error
34+
public "": string = "no nothing"; // No error
35+
public " ": string = "just space"; // No error
36+
public "1 0 1": string = "several numbers and spaces"; // No error
37+
public "NaN": string = "not a number"; // No error
38+
public "-NaN": string = "not a negative number"; // No error
39+
public "hunter2": string = "not a password"; // No error
40+
public "+Infinity": string = "A gillion"; // No error
41+
public "-Infinity": string = "Negative-a-gillion"; // No error
42+
43+
// These fall into the above category, however, they are "trickier";
44+
// these all are *scanned* as numeric literals, but they are not written in
45+
// "canonical" numeric representations.
46+
public "+1": string = "positive number (for the paranoid)"; // No error
47+
public "1e0": string = "just one"; // No error
48+
public "-0e0": string = "just zero"; // No error
49+
public "0xF00D": string = "hex food"; // No error
50+
public "0xBEEF": string = "hex beef"; // No error
51+
public "0123": string = "oct 83"; // No error
52+
public "0.000000000000000000012": string = "should've been in exponential form"; // No error
53+
}
2954

0 commit comments

Comments
 (0)