Skip to content

Commit 7192767

Browse files
committed
Add type checking for computed properties in object literals
1 parent ef06879 commit 7192767

25 files changed

+120
-64
lines changed

Diff for: src/compiler/checker.ts

+17-1
Original file line numberDiff line numberDiff line change
@@ -5395,6 +5395,17 @@ module ts {
53955395
return (+name).toString() === name;
53965396
}
53975397

5398+
function checkComputedPropertyName(node: ComputedPropertyName): void {
5399+
var computedNameType = checkExpression(node.expression);
5400+
5401+
// This will only allow types number, string, or any. Any types more complex will
5402+
// be disallowed, even union types like string | number. In the future, we might consider
5403+
// allowing types like that.
5404+
if ((computedNameType.flags & (TypeFlags.Number | TypeFlags.String | TypeFlags.Any)) === 0) {
5405+
error(node, Diagnostics.A_computed_property_name_must_be_of_type_string_number_or_any);
5406+
}
5407+
}
5408+
53985409
function checkObjectLiteral(node: ObjectLiteralExpression, contextualMapper?: TypeMapper): Type {
53995410
// Grammar checking
54005411
checkGrammarObjectLiteralExpression(node);
@@ -5443,7 +5454,12 @@ module ts {
54435454
checkAccessorDeclaration(<AccessorDeclaration>memberDecl);
54445455
}
54455456

5446-
properties[member.name] = member;
5457+
if (hasComputedNameButNotSymbol(memberDecl)) {
5458+
checkComputedPropertyName(<ComputedPropertyName>memberDecl.name);
5459+
}
5460+
else {
5461+
properties[member.name] = member;
5462+
}
54475463
}
54485464

54495465
var stringIndexType = getIndexType(IndexKind.String);

Diff for: src/compiler/diagnosticInformationMap.generated.ts

+1
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,7 @@ module ts {
299299
Type_0_is_not_an_array_type: { code: 2461, category: DiagnosticCategory.Error, key: "Type '{0}' is not an array type." },
300300
A_rest_element_must_be_last_in_an_array_destructuring_pattern: { code: 2462, category: DiagnosticCategory.Error, key: "A rest element must be last in an array destructuring pattern" },
301301
A_binding_pattern_parameter_cannot_be_optional_in_an_implementation_signature: { code: 2463, category: DiagnosticCategory.Error, key: "A binding pattern parameter cannot be optional in an implementation signature." },
302+
A_computed_property_name_must_be_of_type_string_number_or_any: { code: 2464, category: DiagnosticCategory.Error, key: "A computed property name must be of type 'string', 'number', or 'any'." },
302303
Import_declaration_0_is_using_private_name_1: { code: 4000, category: DiagnosticCategory.Error, key: "Import declaration '{0}' is using private name '{1}'." },
303304
Type_parameter_0_of_exported_class_has_or_is_using_private_name_1: { code: 4002, category: DiagnosticCategory.Error, key: "Type parameter '{0}' of exported class has or is using private name '{1}'." },
304305
Type_parameter_0_of_exported_interface_has_or_is_using_private_name_1: { code: 4004, category: DiagnosticCategory.Error, key: "Type parameter '{0}' of exported interface has or is using private name '{1}'." },

Diff for: src/compiler/diagnosticMessages.json

+6-2
Original file line numberDiff line numberDiff line change
@@ -675,7 +675,7 @@
675675
},
676676
"A parameter property may not be a binding pattern.": {
677677
"category": "Error",
678-
"code": 1187
678+
"code": 1187
679679
},
680680

681681
"Duplicate identifier '{0}'.": {
@@ -1288,7 +1288,11 @@
12881288
},
12891289
"A binding pattern parameter cannot be optional in an implementation signature.": {
12901290
"category": "Error",
1291-
"code": 2463
1291+
"code": 2463
1292+
},
1293+
"A computed property name must be of type 'string', 'number', or 'any'.": {
1294+
"category": "Error",
1295+
"code": 2464
12921296
},
12931297

12941298
"Import declaration '{0}' is using private name '{1}'.": {

Diff for: src/compiler/utilities.ts

+2
Original file line numberDiff line numberDiff line change
@@ -527,6 +527,8 @@ module ts {
527527
return node === (<TypeAssertion>parent).expression;
528528
case SyntaxKind.TemplateSpan:
529529
return node === (<TemplateSpan>parent).expression;
530+
case SyntaxKind.ComputedPropertyName:
531+
return node === (<ComputedPropertyName>parent).expression;
530532
default:
531533
if (isExpression(parent)) {
532534
return true;
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
tests/cases/conformance/es6/functionDeclarations/FunctionDeclaration8_es6.ts(1,11): error TS1167: Computed property names are only available when targeting ECMAScript 6 and higher.
2+
tests/cases/conformance/es6/functionDeclarations/FunctionDeclaration8_es6.ts(1,12): error TS2304: Cannot find name 'yield'.
23
tests/cases/conformance/es6/functionDeclarations/FunctionDeclaration8_es6.ts(1,20): error TS2304: Cannot find name 'foo'.
34

45

5-
==== tests/cases/conformance/es6/functionDeclarations/FunctionDeclaration8_es6.ts (2 errors) ====
6+
==== tests/cases/conformance/es6/functionDeclarations/FunctionDeclaration8_es6.ts (3 errors) ====
67
var v = { [yield]: foo }
78
~~~~~~~
89
!!! error TS1167: Computed property names are only available when targeting ECMAScript 6 and higher.
10+
~~~~~
11+
!!! error TS2304: Cannot find name 'yield'.
912
~~~
1013
!!! error TS2304: Cannot find name 'foo'.
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
tests/cases/conformance/es6/functionDeclarations/FunctionDeclaration9_es6.ts(1,10): error TS9001: Generators are not currently supported.
22
tests/cases/conformance/es6/functionDeclarations/FunctionDeclaration9_es6.ts(2,13): error TS1167: Computed property names are only available when targeting ECMAScript 6 and higher.
3+
tests/cases/conformance/es6/functionDeclarations/FunctionDeclaration9_es6.ts(2,14): error TS9000: 'yield' expressions are not currently supported.
34

45

5-
==== tests/cases/conformance/es6/functionDeclarations/FunctionDeclaration9_es6.ts (2 errors) ====
6+
==== tests/cases/conformance/es6/functionDeclarations/FunctionDeclaration9_es6.ts (3 errors) ====
67
function * foo() {
78
~
89
!!! error TS9001: Generators are not currently supported.
910
var v = { [yield]: foo }
1011
~~~~~~~
1112
!!! error TS1167: Computed property names are only available when targeting ECMAScript 6 and higher.
13+
~~~~~
14+
!!! error TS9000: 'yield' expressions are not currently supported.
1215
}
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
tests/cases/conformance/es6/functionPropertyAssignments/FunctionPropertyAssignments5_es6.ts(1,11): error TS9001: Generators are not currently supported.
22
tests/cases/conformance/es6/functionPropertyAssignments/FunctionPropertyAssignments5_es6.ts(1,12): error TS1167: Computed property names are only available when targeting ECMAScript 6 and higher.
3+
tests/cases/conformance/es6/functionPropertyAssignments/FunctionPropertyAssignments5_es6.ts(1,13): error TS2304: Cannot find name 'foo'.
34

45

5-
==== tests/cases/conformance/es6/functionPropertyAssignments/FunctionPropertyAssignments5_es6.ts (2 errors) ====
6+
==== tests/cases/conformance/es6/functionPropertyAssignments/FunctionPropertyAssignments5_es6.ts (3 errors) ====
67
var v = { *[foo()]() { } }
78
~
89
!!! error TS9001: Generators are not currently supported.
910
~~~~~~~
10-
!!! error TS1167: Computed property names are only available when targeting ECMAScript 6 and higher.
11+
!!! error TS1167: Computed property names are only available when targeting ECMAScript 6 and higher.
12+
~~~
13+
!!! error TS2304: Cannot find name 'foo'.
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
1+
tests/cases/conformance/parser/ecmascript6/ComputedPropertyNames/parserComputedPropertyName1.ts(1,12): error TS2304: Cannot find name 'e'.
12
tests/cases/conformance/parser/ecmascript6/ComputedPropertyNames/parserComputedPropertyName1.ts(1,15): error TS1005: ':' expected.
23

34

4-
==== tests/cases/conformance/parser/ecmascript6/ComputedPropertyNames/parserComputedPropertyName1.ts (1 errors) ====
5+
==== tests/cases/conformance/parser/ecmascript6/ComputedPropertyNames/parserComputedPropertyName1.ts (2 errors) ====
56
var v = { [e] };
7+
~
8+
!!! error TS2304: Cannot find name 'e'.
69
~
710
!!! error TS1005: ':' expected.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
tests/cases/conformance/parser/ecmascript6/ComputedPropertyNames/parserComputedPropertyName17.ts(1,16): error TS2304: Cannot find name 'e'.
2+
3+
4+
==== tests/cases/conformance/parser/ecmascript6/ComputedPropertyNames/parserComputedPropertyName17.ts (1 errors) ====
5+
var v = { set [e](v) { } }
6+
~
7+
!!! error TS2304: Cannot find name 'e'.

Diff for: tests/baselines/reference/parserComputedPropertyName17.types

-7
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
tests/cases/conformance/parser/ecmascript6/ComputedPropertyNames/parserComputedPropertyName2.ts(1,12): error TS2304: Cannot find name 'e'.
2+
3+
4+
==== tests/cases/conformance/parser/ecmascript6/ComputedPropertyNames/parserComputedPropertyName2.ts (1 errors) ====
5+
var v = { [e]: 1 };
6+
~
7+
!!! error TS2304: Cannot find name 'e'.

Diff for: tests/baselines/reference/parserComputedPropertyName2.types

-6
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
tests/cases/conformance/parser/ecmascript6/ComputedPropertyNames/parserComputedPropertyName3.ts(1,12): error TS2304: Cannot find name 'e'.
2+
3+
4+
==== tests/cases/conformance/parser/ecmascript6/ComputedPropertyNames/parserComputedPropertyName3.ts (1 errors) ====
5+
var v = { [e]() { } };
6+
~
7+
!!! error TS2304: Cannot find name 'e'.

Diff for: tests/baselines/reference/parserComputedPropertyName3.types

-6
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
tests/cases/conformance/parser/ecmascript6/ComputedPropertyNames/parserComputedPropertyName37.ts(2,6): error TS2304: Cannot find name 'public'.
2+
3+
4+
==== tests/cases/conformance/parser/ecmascript6/ComputedPropertyNames/parserComputedPropertyName37.ts (1 errors) ====
5+
var v = {
6+
[public]: 0
7+
~~~~~~
8+
!!! error TS2304: Cannot find name 'public'.
9+
};

Diff for: tests/baselines/reference/parserComputedPropertyName37.types

-9
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
tests/cases/conformance/parser/ecmascript6/ComputedPropertyNames/parserComputedPropertyName4.ts(1,15): error TS2378: A 'get' accessor must return a value or consist of a single 'throw' statement.
2+
tests/cases/conformance/parser/ecmascript6/ComputedPropertyNames/parserComputedPropertyName4.ts(1,16): error TS2304: Cannot find name 'e'.
23

34

4-
==== tests/cases/conformance/parser/ecmascript6/ComputedPropertyNames/parserComputedPropertyName4.ts (1 errors) ====
5+
==== tests/cases/conformance/parser/ecmascript6/ComputedPropertyNames/parserComputedPropertyName4.ts (2 errors) ====
56
var v = { get [e]() { } };
67
~~~
7-
!!! error TS2378: A 'get' accessor must return a value or consist of a single 'throw' statement.
8+
!!! error TS2378: A 'get' accessor must return a value or consist of a single 'throw' statement.
9+
~
10+
!!! error TS2304: Cannot find name 'e'.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
tests/cases/conformance/parser/ecmascript6/ComputedPropertyNames/parserComputedPropertyName41.ts(2,5): error TS2464: A computed property name must be of type 'string', 'number', or 'any'.
2+
3+
4+
==== tests/cases/conformance/parser/ecmascript6/ComputedPropertyNames/parserComputedPropertyName41.ts (1 errors) ====
5+
var v = {
6+
[0 in []]: true
7+
~~~~~~~~~
8+
!!! error TS2464: A computed property name must be of type 'string', 'number', or 'any'.
9+
}

Diff for: tests/baselines/reference/parserComputedPropertyName41.types

-9
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
tests/cases/conformance/parser/ecmascript6/ComputedPropertyNames/parserComputedPropertyName5.ts(1,22): error TS2378: A 'get' accessor must return a value or consist of a single 'throw' statement.
2+
tests/cases/conformance/parser/ecmascript6/ComputedPropertyNames/parserComputedPropertyName5.ts(1,23): error TS2304: Cannot find name 'e'.
23

34

4-
==== tests/cases/conformance/parser/ecmascript6/ComputedPropertyNames/parserComputedPropertyName5.ts (1 errors) ====
5+
==== tests/cases/conformance/parser/ecmascript6/ComputedPropertyNames/parserComputedPropertyName5.ts (2 errors) ====
56
var v = { public get [e]() { } };
67
~~~
7-
!!! error TS2378: A 'get' accessor must return a value or consist of a single 'throw' statement.
8+
!!! error TS2378: A 'get' accessor must return a value or consist of a single 'throw' statement.
9+
~
10+
!!! error TS2304: Cannot find name 'e'.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
tests/cases/conformance/parser/ecmascript6/ComputedPropertyNames/parserComputedPropertyName6.ts(1,12): error TS2304: Cannot find name 'e'.
2+
tests/cases/conformance/parser/ecmascript6/ComputedPropertyNames/parserComputedPropertyName6.ts(1,20): error TS2304: Cannot find name 'e'.
3+
tests/cases/conformance/parser/ecmascript6/ComputedPropertyNames/parserComputedPropertyName6.ts(1,24): error TS2304: Cannot find name 'e'.
4+
5+
6+
==== tests/cases/conformance/parser/ecmascript6/ComputedPropertyNames/parserComputedPropertyName6.ts (3 errors) ====
7+
var v = { [e]: 1, [e + e]: 2 };
8+
~
9+
!!! error TS2304: Cannot find name 'e'.
10+
~
11+
!!! error TS2304: Cannot find name 'e'.
12+
~
13+
!!! error TS2304: Cannot find name 'e'.

Diff for: tests/baselines/reference/parserComputedPropertyName6.types

-9
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
tests/cases/conformance/parser/ecmascript5/ComputedPropertyNames/parserES5ComputedPropertyName2.ts(1,11): error TS1167: Computed property names are only available when targeting ECMAScript 6 and higher.
2+
tests/cases/conformance/parser/ecmascript5/ComputedPropertyNames/parserES5ComputedPropertyName2.ts(1,12): error TS2304: Cannot find name 'e'.
23

34

4-
==== tests/cases/conformance/parser/ecmascript5/ComputedPropertyNames/parserES5ComputedPropertyName2.ts (1 errors) ====
5+
==== tests/cases/conformance/parser/ecmascript5/ComputedPropertyNames/parserES5ComputedPropertyName2.ts (2 errors) ====
56
var v = { [e]: 1 };
67
~~~
7-
!!! error TS1167: Computed property names are only available when targeting ECMAScript 6 and higher.
8+
!!! error TS1167: Computed property names are only available when targeting ECMAScript 6 and higher.
9+
~
10+
!!! error TS2304: Cannot find name 'e'.
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
tests/cases/conformance/parser/ecmascript5/ComputedPropertyNames/parserES5ComputedPropertyName3.ts(1,11): error TS1167: Computed property names are only available when targeting ECMAScript 6 and higher.
2+
tests/cases/conformance/parser/ecmascript5/ComputedPropertyNames/parserES5ComputedPropertyName3.ts(1,12): error TS2304: Cannot find name 'e'.
23

34

4-
==== tests/cases/conformance/parser/ecmascript5/ComputedPropertyNames/parserES5ComputedPropertyName3.ts (1 errors) ====
5+
==== tests/cases/conformance/parser/ecmascript5/ComputedPropertyNames/parserES5ComputedPropertyName3.ts (2 errors) ====
56
var v = { [e]() { } };
67
~~~
7-
!!! error TS1167: Computed property names are only available when targeting ECMAScript 6 and higher.
8+
!!! error TS1167: Computed property names are only available when targeting ECMAScript 6 and higher.
9+
~
10+
!!! error TS2304: Cannot find name 'e'.
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
tests/cases/conformance/parser/ecmascript5/ComputedPropertyNames/parserES5ComputedPropertyName4.ts(1,15): error TS1167: Computed property names are only available when targeting ECMAScript 6 and higher.
22
tests/cases/conformance/parser/ecmascript5/ComputedPropertyNames/parserES5ComputedPropertyName4.ts(1,15): error TS2378: A 'get' accessor must return a value or consist of a single 'throw' statement.
3+
tests/cases/conformance/parser/ecmascript5/ComputedPropertyNames/parserES5ComputedPropertyName4.ts(1,16): error TS2304: Cannot find name 'e'.
34

45

5-
==== tests/cases/conformance/parser/ecmascript5/ComputedPropertyNames/parserES5ComputedPropertyName4.ts (2 errors) ====
6+
==== tests/cases/conformance/parser/ecmascript5/ComputedPropertyNames/parserES5ComputedPropertyName4.ts (3 errors) ====
67
var v = { get [e]() { } };
78
~~~
89
!!! error TS1167: Computed property names are only available when targeting ECMAScript 6 and higher.
910
~~~
10-
!!! error TS2378: A 'get' accessor must return a value or consist of a single 'throw' statement.
11+
!!! error TS2378: A 'get' accessor must return a value or consist of a single 'throw' statement.
12+
~
13+
!!! error TS2304: Cannot find name 'e'.

0 commit comments

Comments
 (0)