@@ -7313,15 +7313,15 @@ namespace ts {
73137313 }
73147314
73157315 function checkObjectLiteral(node: ObjectLiteralExpression, contextualMapper?: TypeMapper): Type {
7316+ let inDestructuringPattern = isAssignmentTarget(node);
73167317 // Grammar checking
7317- checkGrammarObjectLiteralExpression(node);
7318+ checkGrammarObjectLiteralExpression(node, inDestructuringPattern );
73187319
73197320 let propertiesTable: SymbolTable = {};
73207321 let propertiesArray: Symbol[] = [];
73217322 let contextualType = getContextualType(node);
73227323 let contextualTypeHasPattern = contextualType && contextualType.pattern &&
73237324 (contextualType.pattern.kind === SyntaxKind.ObjectBindingPattern || contextualType.pattern.kind === SyntaxKind.ObjectLiteralExpression);
7324- let inDestructuringPattern = isAssignmentTarget(node);
73257325 let typeFlags: TypeFlags = 0;
73267326
73277327 for (let memberDecl of node.properties) {
@@ -7345,7 +7345,10 @@ namespace ts {
73457345 if (inDestructuringPattern) {
73467346 // If object literal is an assignment pattern and if the assignment pattern specifies a default value
73477347 // for the property, make the property optional.
7348- if (memberDecl.kind === SyntaxKind.PropertyAssignment && hasDefaultValue((<PropertyAssignment>memberDecl).initializer)) {
7348+ const isOptional =
7349+ (memberDecl.kind === SyntaxKind.PropertyAssignment && hasDefaultValue((<PropertyAssignment>memberDecl).initializer)) ||
7350+ (memberDecl.kind === SyntaxKind.ShorthandPropertyAssignment && (<ShorthandPropertyAssignment>memberDecl).objectAssignmentInitializer);
7351+ if (isOptional) {
73497352 prop.flags |= SymbolFlags.Optional;
73507353 }
73517354 }
@@ -9909,32 +9912,32 @@ namespace ts {
99099912 return (symbol.flags & SymbolFlags.ConstEnum) !== 0;
99109913 }
99119914
9912- function checkInstanceOfExpression(node: BinaryExpression , leftType: Type, rightType: Type): Type {
9915+ function checkInstanceOfExpression(left: Expression, right: Expression , leftType: Type, rightType: Type): Type {
99139916 // TypeScript 1.0 spec (April 2014): 4.15.4
99149917 // The instanceof operator requires the left operand to be of type Any, an object type, or a type parameter type,
99159918 // and the right operand to be of type Any or a subtype of the 'Function' interface type.
99169919 // The result is always of the Boolean primitive type.
99179920 // NOTE: do not raise error if leftType is unknown as related error was already reported
99189921 if (allConstituentTypesHaveKind(leftType, TypeFlags.Primitive)) {
9919- error(node. left, Diagnostics.The_left_hand_side_of_an_instanceof_expression_must_be_of_type_any_an_object_type_or_a_type_parameter);
9922+ error(left, Diagnostics.The_left_hand_side_of_an_instanceof_expression_must_be_of_type_any_an_object_type_or_a_type_parameter);
99209923 }
99219924 // NOTE: do not raise error if right is unknown as related error was already reported
99229925 if (!(isTypeAny(rightType) || isTypeSubtypeOf(rightType, globalFunctionType))) {
9923- error(node. right, Diagnostics.The_right_hand_side_of_an_instanceof_expression_must_be_of_type_any_or_of_a_type_assignable_to_the_Function_interface_type);
9926+ error(right, Diagnostics.The_right_hand_side_of_an_instanceof_expression_must_be_of_type_any_or_of_a_type_assignable_to_the_Function_interface_type);
99249927 }
99259928 return booleanType;
99269929 }
99279930
9928- function checkInExpression(node: BinaryExpression , leftType: Type, rightType: Type): Type {
9931+ function checkInExpression(left: Expression, right: Expression , leftType: Type, rightType: Type): Type {
99299932 // TypeScript 1.0 spec (April 2014): 4.15.5
99309933 // The in operator requires the left operand to be of type Any, the String primitive type, or the Number primitive type,
99319934 // and the right operand to be of type Any, an object type, or a type parameter type.
99329935 // The result is always of the Boolean primitive type.
99339936 if (!isTypeAnyOrAllConstituentTypesHaveKind(leftType, TypeFlags.StringLike | TypeFlags.NumberLike | TypeFlags.ESSymbol)) {
9934- error(node. left, Diagnostics.The_left_hand_side_of_an_in_expression_must_be_of_type_any_string_number_or_symbol);
9937+ error(left, Diagnostics.The_left_hand_side_of_an_in_expression_must_be_of_type_any_string_number_or_symbol);
99359938 }
99369939 if (!isTypeAnyOrAllConstituentTypesHaveKind(rightType, TypeFlags.ObjectType | TypeFlags.TypeParameter)) {
9937- error(node. right, Diagnostics.The_right_hand_side_of_an_in_expression_must_be_of_type_any_an_object_type_or_a_type_parameter);
9940+ error(right, Diagnostics.The_right_hand_side_of_an_in_expression_must_be_of_type_any_an_object_type_or_a_type_parameter);
99389941 }
99399942 return booleanType;
99409943 }
@@ -9951,7 +9954,12 @@ namespace ts {
99519954 isNumericLiteralName(name.text) && getIndexTypeOfType(sourceType, IndexKind.Number) ||
99529955 getIndexTypeOfType(sourceType, IndexKind.String);
99539956 if (type) {
9954- checkDestructuringAssignment((<PropertyAssignment>p).initializer || name, type);
9957+ if (p.kind === SyntaxKind.ShorthandPropertyAssignment) {
9958+ checkDestructuringAssignment(<ShorthandPropertyAssignment>p, type);
9959+ }
9960+ else {
9961+ checkDestructuringAssignment((<PropertyAssignment>p).initializer || name, type);
9962+ }
99559963 }
99569964 else {
99579965 error(name, Diagnostics.Type_0_has_no_property_1_and_no_string_index_signature, typeToString(sourceType), declarationNameToString(name));
@@ -10011,7 +10019,19 @@ namespace ts {
1001110019 return sourceType;
1001210020 }
1001310021
10014- function checkDestructuringAssignment(target: Expression, sourceType: Type, contextualMapper?: TypeMapper): Type {
10022+ function checkDestructuringAssignment(exprOrAssignment: Expression | ShorthandPropertyAssignment, sourceType: Type, contextualMapper?: TypeMapper): Type {
10023+ let target: Expression;
10024+ if (exprOrAssignment.kind === SyntaxKind.ShorthandPropertyAssignment) {
10025+ const prop = <ShorthandPropertyAssignment>exprOrAssignment;
10026+ if (prop.objectAssignmentInitializer) {
10027+ checkBinaryLikeExpression(prop.name, prop.equalsToken, prop.objectAssignmentInitializer, contextualMapper);
10028+ }
10029+ target = (<ShorthandPropertyAssignment>exprOrAssignment).name;
10030+ }
10031+ else {
10032+ target = <Expression>exprOrAssignment;
10033+ }
10034+
1001510035 if (target.kind === SyntaxKind.BinaryExpression && (<BinaryExpression>target).operatorToken.kind === SyntaxKind.EqualsToken) {
1001610036 checkBinaryExpression(<BinaryExpression>target, contextualMapper);
1001710037 target = (<BinaryExpression>target).left;
@@ -10034,12 +10054,16 @@ namespace ts {
1003410054 }
1003510055
1003610056 function checkBinaryExpression(node: BinaryExpression, contextualMapper?: TypeMapper) {
10037- let operator = node.operatorToken.kind;
10038- if (operator === SyntaxKind.EqualsToken && (node.left.kind === SyntaxKind.ObjectLiteralExpression || node.left.kind === SyntaxKind.ArrayLiteralExpression)) {
10039- return checkDestructuringAssignment(node.left, checkExpression(node.right, contextualMapper), contextualMapper);
10057+ return checkBinaryLikeExpression(node.left, node.operatorToken, node.right, contextualMapper, node);
10058+ }
10059+
10060+ function checkBinaryLikeExpression(left: Expression, operatorToken: Node, right: Expression, contextualMapper?: TypeMapper, errorNode?: Node) {
10061+ let operator = operatorToken.kind;
10062+ if (operator === SyntaxKind.EqualsToken && (left.kind === SyntaxKind.ObjectLiteralExpression || left.kind === SyntaxKind.ArrayLiteralExpression)) {
10063+ return checkDestructuringAssignment(left, checkExpression(right, contextualMapper), contextualMapper);
1004010064 }
10041- let leftType = checkExpression(node. left, contextualMapper);
10042- let rightType = checkExpression(node. right, contextualMapper);
10065+ let leftType = checkExpression(left, contextualMapper);
10066+ let rightType = checkExpression(right, contextualMapper);
1004310067 switch (operator) {
1004410068 case SyntaxKind.AsteriskToken:
1004510069 case SyntaxKind.AsteriskEqualsToken:
@@ -10075,13 +10099,13 @@ namespace ts {
1007510099 // try and return them a helpful suggestion
1007610100 if ((leftType.flags & TypeFlags.Boolean) &&
1007710101 (rightType.flags & TypeFlags.Boolean) &&
10078- (suggestedOperator = getSuggestedBooleanOperator(node. operatorToken.kind)) !== undefined) {
10079- error(node , Diagnostics.The_0_operator_is_not_allowed_for_boolean_types_Consider_using_1_instead, tokenToString(node. operatorToken.kind), tokenToString(suggestedOperator));
10102+ (suggestedOperator = getSuggestedBooleanOperator(operatorToken.kind)) !== undefined) {
10103+ error(errorNode || operatorToken , Diagnostics.The_0_operator_is_not_allowed_for_boolean_types_Consider_using_1_instead, tokenToString(operatorToken.kind), tokenToString(suggestedOperator));
1008010104 }
1008110105 else {
1008210106 // otherwise just check each operand separately and report errors as normal
10083- let leftOk = checkArithmeticOperandType(node. left, leftType, Diagnostics.The_left_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_or_an_enum_type);
10084- let rightOk = checkArithmeticOperandType(node. right, rightType, Diagnostics.The_right_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_or_an_enum_type);
10107+ let leftOk = checkArithmeticOperandType(left, leftType, Diagnostics.The_left_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_or_an_enum_type);
10108+ let rightOk = checkArithmeticOperandType(right, rightType, Diagnostics.The_right_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_or_an_enum_type);
1008510109 if (leftOk && rightOk) {
1008610110 checkAssignmentOperator(numberType);
1008710111 }
@@ -10147,9 +10171,9 @@ namespace ts {
1014710171 }
1014810172 return booleanType;
1014910173 case SyntaxKind.InstanceOfKeyword:
10150- return checkInstanceOfExpression(node , leftType, rightType);
10174+ return checkInstanceOfExpression(left, right , leftType, rightType);
1015110175 case SyntaxKind.InKeyword:
10152- return checkInExpression(node , leftType, rightType);
10176+ return checkInExpression(left, right , leftType, rightType);
1015310177 case SyntaxKind.AmpersandAmpersandToken:
1015410178 return rightType;
1015510179 case SyntaxKind.BarBarToken:
@@ -10164,8 +10188,8 @@ namespace ts {
1016410188 // Return true if there was no error, false if there was an error.
1016510189 function checkForDisallowedESSymbolOperand(operator: SyntaxKind): boolean {
1016610190 let offendingSymbolOperand =
10167- someConstituentTypeHasKind(leftType, TypeFlags.ESSymbol) ? node. left :
10168- someConstituentTypeHasKind(rightType, TypeFlags.ESSymbol) ? node. right :
10191+ someConstituentTypeHasKind(leftType, TypeFlags.ESSymbol) ? left :
10192+ someConstituentTypeHasKind(rightType, TypeFlags.ESSymbol) ? right :
1016910193 undefined;
1017010194 if (offendingSymbolOperand) {
1017110195 error(offendingSymbolOperand, Diagnostics.The_0_operator_cannot_be_applied_to_type_symbol, tokenToString(operator));
@@ -10199,17 +10223,17 @@ namespace ts {
1019910223 // requires VarExpr to be classified as a reference
1020010224 // A compound assignment furthermore requires VarExpr to be classified as a reference (section 4.1)
1020110225 // and the type of the non - compound operation to be assignable to the type of VarExpr.
10202- let ok = checkReferenceExpression(node. left, Diagnostics.Invalid_left_hand_side_of_assignment_expression, Diagnostics.Left_hand_side_of_assignment_expression_cannot_be_a_constant);
10226+ let ok = checkReferenceExpression(left, Diagnostics.Invalid_left_hand_side_of_assignment_expression, Diagnostics.Left_hand_side_of_assignment_expression_cannot_be_a_constant);
1020310227 // Use default messages
1020410228 if (ok) {
1020510229 // to avoid cascading errors check assignability only if 'isReference' check succeeded and no errors were reported
10206- checkTypeAssignableTo(valueType, leftType, node. left, /*headMessage*/ undefined);
10230+ checkTypeAssignableTo(valueType, leftType, left, /*headMessage*/ undefined);
1020710231 }
1020810232 }
1020910233 }
1021010234
1021110235 function reportOperatorError() {
10212- error(node , Diagnostics.Operator_0_cannot_be_applied_to_types_1_and_2, tokenToString(node. operatorToken.kind), typeToString(leftType), typeToString(rightType));
10236+ error(errorNode || operatorToken , Diagnostics.Operator_0_cannot_be_applied_to_types_1_and_2, tokenToString(operatorToken.kind), typeToString(leftType), typeToString(rightType));
1021310237 }
1021410238 }
1021510239
@@ -15421,7 +15445,7 @@ namespace ts {
1542115445 }
1542215446 }
1542315447
15424- function checkGrammarObjectLiteralExpression(node: ObjectLiteralExpression) {
15448+ function checkGrammarObjectLiteralExpression(node: ObjectLiteralExpression, inDestructuring: boolean ) {
1542515449 let seen: Map<SymbolFlags> = {};
1542615450 let Property = 1;
1542715451 let GetAccessor = 2;
@@ -15437,6 +15461,12 @@ namespace ts {
1543715461 continue;
1543815462 }
1543915463
15464+ if (prop.kind === SyntaxKind.ShorthandPropertyAssignment && !inDestructuring && (<ShorthandPropertyAssignment>prop).objectAssignmentInitializer) {
15465+ // having objectAssignmentInitializer is only valid in ObjectAssignmentPattern
15466+ // outside of destructuring it is a syntax error
15467+ return grammarErrorOnNode((<ShorthandPropertyAssignment>prop).equalsToken, Diagnostics.can_only_be_used_in_an_object_literal_property_inside_a_destructuring_assignment);
15468+ }
15469+
1544015470 // ECMA-262 11.1.5 Object Initialiser
1544115471 // If previous is not undefined then throw a SyntaxError exception if any of the following conditions are true
1544215472 // a.This production is contained in strict code and IsDataDescriptor(previous) is true and
0 commit comments