Add type checking for computed properties in object literals

This commit is contained in:
Jason Freeman
2015-01-09 17:46:16 -08:00
parent ef06879a75
commit 7192767a00
25 changed files with 120 additions and 64 deletions

View File

@@ -5395,6 +5395,17 @@ module ts {
return (+name).toString() === name;
}
function checkComputedPropertyName(node: ComputedPropertyName): void {
var computedNameType = checkExpression(node.expression);
// This will only allow types number, string, or any. Any types more complex will
// be disallowed, even union types like string | number. In the future, we might consider
// allowing types like that.
if ((computedNameType.flags & (TypeFlags.Number | TypeFlags.String | TypeFlags.Any)) === 0) {
error(node, Diagnostics.A_computed_property_name_must_be_of_type_string_number_or_any);
}
}
function checkObjectLiteral(node: ObjectLiteralExpression, contextualMapper?: TypeMapper): Type {
// Grammar checking
checkGrammarObjectLiteralExpression(node);
@@ -5443,7 +5454,12 @@ module ts {
checkAccessorDeclaration(<AccessorDeclaration>memberDecl);
}
properties[member.name] = member;
if (hasComputedNameButNotSymbol(memberDecl)) {
checkComputedPropertyName(<ComputedPropertyName>memberDecl.name);
}
else {
properties[member.name] = member;
}
}
var stringIndexType = getIndexType(IndexKind.String);

View File

@@ -299,6 +299,7 @@ module ts {
Type_0_is_not_an_array_type: { code: 2461, category: DiagnosticCategory.Error, key: "Type '{0}' is not an array type." },
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" },
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." },
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'." },
Import_declaration_0_is_using_private_name_1: { code: 4000, category: DiagnosticCategory.Error, key: "Import declaration '{0}' is using private name '{1}'." },
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}'." },
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}'." },

View File

@@ -675,7 +675,7 @@
},
"A parameter property may not be a binding pattern.": {
"category": "Error",
"code": 1187
"code": 1187
},
"Duplicate identifier '{0}'.": {
@@ -1288,7 +1288,11 @@
},
"A binding pattern parameter cannot be optional in an implementation signature.": {
"category": "Error",
"code": 2463
"code": 2463
},
"A computed property name must be of type 'string', 'number', or 'any'.": {
"category": "Error",
"code": 2464
},
"Import declaration '{0}' is using private name '{1}'.": {

View File

@@ -527,6 +527,8 @@ module ts {
return node === (<TypeAssertion>parent).expression;
case SyntaxKind.TemplateSpan:
return node === (<TemplateSpan>parent).expression;
case SyntaxKind.ComputedPropertyName:
return node === (<ComputedPropertyName>parent).expression;
default:
if (isExpression(parent)) {
return true;