parse/check/emit shorthand property assignment in destructuring

This commit is contained in:
Vladimir Matveev 2015-10-05 13:46:56 -07:00
parent e168910ca2
commit a975895e4d
13 changed files with 1125 additions and 38 deletions

View file

@ -7313,15 +7313,15 @@ namespace ts {
}
function checkObjectLiteral(node: ObjectLiteralExpression, contextualMapper?: TypeMapper): Type {
let inDestructuringPattern = isAssignmentTarget(node);
// Grammar checking
checkGrammarObjectLiteralExpression(node);
checkGrammarObjectLiteralExpression(node, inDestructuringPattern);
let propertiesTable: SymbolTable = {};
let propertiesArray: Symbol[] = [];
let contextualType = getContextualType(node);
let contextualTypeHasPattern = contextualType && contextualType.pattern &&
(contextualType.pattern.kind === SyntaxKind.ObjectBindingPattern || contextualType.pattern.kind === SyntaxKind.ObjectLiteralExpression);
let inDestructuringPattern = isAssignmentTarget(node);
let typeFlags: TypeFlags = 0;
for (let memberDecl of node.properties) {
@ -7345,7 +7345,10 @@ namespace ts {
if (inDestructuringPattern) {
// If object literal is an assignment pattern and if the assignment pattern specifies a default value
// for the property, make the property optional.
if (memberDecl.kind === SyntaxKind.PropertyAssignment && hasDefaultValue((<PropertyAssignment>memberDecl).initializer)) {
const isOptional =
(memberDecl.kind === SyntaxKind.PropertyAssignment && hasDefaultValue((<PropertyAssignment>memberDecl).initializer)) ||
(memberDecl.kind === SyntaxKind.ShorthandPropertyAssignment && (<ShorthandPropertyAssignment>memberDecl).objectAssignmentInitializer);
if (isOptional) {
prop.flags |= SymbolFlags.Optional;
}
}
@ -9902,32 +9905,32 @@ namespace ts {
return (symbol.flags & SymbolFlags.ConstEnum) !== 0;
}
function checkInstanceOfExpression(node: BinaryExpression, leftType: Type, rightType: Type): Type {
function checkInstanceOfExpression(left: Expression, right: Expression, leftType: Type, rightType: Type): Type {
// TypeScript 1.0 spec (April 2014): 4.15.4
// The instanceof operator requires the left operand to be of type Any, an object type, or a type parameter type,
// and the right operand to be of type Any or a subtype of the 'Function' interface type.
// The result is always of the Boolean primitive type.
// NOTE: do not raise error if leftType is unknown as related error was already reported
if (allConstituentTypesHaveKind(leftType, TypeFlags.Primitive)) {
error(node.left, Diagnostics.The_left_hand_side_of_an_instanceof_expression_must_be_of_type_any_an_object_type_or_a_type_parameter);
error(left, Diagnostics.The_left_hand_side_of_an_instanceof_expression_must_be_of_type_any_an_object_type_or_a_type_parameter);
}
// NOTE: do not raise error if right is unknown as related error was already reported
if (!(isTypeAny(rightType) || isTypeSubtypeOf(rightType, globalFunctionType))) {
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);
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);
}
return booleanType;
}
function checkInExpression(node: BinaryExpression, leftType: Type, rightType: Type): Type {
function checkInExpression(left: Expression, right: Expression, leftType: Type, rightType: Type): Type {
// TypeScript 1.0 spec (April 2014): 4.15.5
// The in operator requires the left operand to be of type Any, the String primitive type, or the Number primitive type,
// and the right operand to be of type Any, an object type, or a type parameter type.
// The result is always of the Boolean primitive type.
if (!isTypeAnyOrAllConstituentTypesHaveKind(leftType, TypeFlags.StringLike | TypeFlags.NumberLike | TypeFlags.ESSymbol)) {
error(node.left, Diagnostics.The_left_hand_side_of_an_in_expression_must_be_of_type_any_string_number_or_symbol);
error(left, Diagnostics.The_left_hand_side_of_an_in_expression_must_be_of_type_any_string_number_or_symbol);
}
if (!isTypeAnyOrAllConstituentTypesHaveKind(rightType, TypeFlags.ObjectType | TypeFlags.TypeParameter)) {
error(node.right, Diagnostics.The_right_hand_side_of_an_in_expression_must_be_of_type_any_an_object_type_or_a_type_parameter);
error(right, Diagnostics.The_right_hand_side_of_an_in_expression_must_be_of_type_any_an_object_type_or_a_type_parameter);
}
return booleanType;
}
@ -9944,7 +9947,12 @@ namespace ts {
isNumericLiteralName(name.text) && getIndexTypeOfType(sourceType, IndexKind.Number) ||
getIndexTypeOfType(sourceType, IndexKind.String);
if (type) {
checkDestructuringAssignment((<PropertyAssignment>p).initializer || name, type);
if (p.kind === SyntaxKind.ShorthandPropertyAssignment) {
checkDestructuringAssignment(<ShorthandPropertyAssignment>p, type);
}
else {
checkDestructuringAssignment((<PropertyAssignment>p).initializer || name, type);
}
}
else {
error(name, Diagnostics.Type_0_has_no_property_1_and_no_string_index_signature, typeToString(sourceType), declarationNameToString(name));
@ -10004,7 +10012,19 @@ namespace ts {
return sourceType;
}
function checkDestructuringAssignment(target: Expression, sourceType: Type, contextualMapper?: TypeMapper): Type {
function checkDestructuringAssignment(exprOrAssignment: Expression | ShorthandPropertyAssignment, sourceType: Type, contextualMapper?: TypeMapper): Type {
let target: Expression;
if (exprOrAssignment.kind === SyntaxKind.ShorthandPropertyAssignment) {
const prop = <ShorthandPropertyAssignment>exprOrAssignment;
if (prop.objectAssignmentInitializer) {
checkBinaryLikeExpression(prop.name, prop.equalsToken, prop.objectAssignmentInitializer, contextualMapper);
}
target = (<ShorthandPropertyAssignment>exprOrAssignment).name;
}
else {
target = <Expression>exprOrAssignment;
}
if (target.kind === SyntaxKind.BinaryExpression && (<BinaryExpression>target).operatorToken.kind === SyntaxKind.EqualsToken) {
checkBinaryExpression(<BinaryExpression>target, contextualMapper);
target = (<BinaryExpression>target).left;
@ -10027,12 +10047,16 @@ namespace ts {
}
function checkBinaryExpression(node: BinaryExpression, contextualMapper?: TypeMapper) {
let operator = node.operatorToken.kind;
if (operator === SyntaxKind.EqualsToken && (node.left.kind === SyntaxKind.ObjectLiteralExpression || node.left.kind === SyntaxKind.ArrayLiteralExpression)) {
return checkDestructuringAssignment(node.left, checkExpression(node.right, contextualMapper), contextualMapper);
return checkBinaryLikeExpression(node.left, node.operatorToken, node.right, contextualMapper, node);
}
function checkBinaryLikeExpression(left: Expression, operatorToken: Node, right: Expression, contextualMapper?: TypeMapper, errorNode?: Node) {
let operator = operatorToken.kind;
if (operator === SyntaxKind.EqualsToken && (left.kind === SyntaxKind.ObjectLiteralExpression || left.kind === SyntaxKind.ArrayLiteralExpression)) {
return checkDestructuringAssignment(left, checkExpression(right, contextualMapper), contextualMapper);
}
let leftType = checkExpression(node.left, contextualMapper);
let rightType = checkExpression(node.right, contextualMapper);
let leftType = checkExpression(left, contextualMapper);
let rightType = checkExpression(right, contextualMapper);
switch (operator) {
case SyntaxKind.AsteriskToken:
case SyntaxKind.AsteriskEqualsToken:
@ -10068,13 +10092,13 @@ namespace ts {
// try and return them a helpful suggestion
if ((leftType.flags & TypeFlags.Boolean) &&
(rightType.flags & TypeFlags.Boolean) &&
(suggestedOperator = getSuggestedBooleanOperator(node.operatorToken.kind)) !== undefined) {
error(node, Diagnostics.The_0_operator_is_not_allowed_for_boolean_types_Consider_using_1_instead, tokenToString(node.operatorToken.kind), tokenToString(suggestedOperator));
(suggestedOperator = getSuggestedBooleanOperator(operatorToken.kind)) !== undefined) {
error(errorNode || operatorToken, Diagnostics.The_0_operator_is_not_allowed_for_boolean_types_Consider_using_1_instead, tokenToString(operatorToken.kind), tokenToString(suggestedOperator));
}
else {
// otherwise just check each operand separately and report errors as normal
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);
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);
let leftOk = checkArithmeticOperandType(left, leftType, Diagnostics.The_left_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_or_an_enum_type);
let rightOk = checkArithmeticOperandType(right, rightType, Diagnostics.The_right_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_or_an_enum_type);
if (leftOk && rightOk) {
checkAssignmentOperator(numberType);
}
@ -10140,9 +10164,9 @@ namespace ts {
}
return booleanType;
case SyntaxKind.InstanceOfKeyword:
return checkInstanceOfExpression(node, leftType, rightType);
return checkInstanceOfExpression(left, right, leftType, rightType);
case SyntaxKind.InKeyword:
return checkInExpression(node, leftType, rightType);
return checkInExpression(left, right, leftType, rightType);
case SyntaxKind.AmpersandAmpersandToken:
return rightType;
case SyntaxKind.BarBarToken:
@ -10157,8 +10181,8 @@ namespace ts {
// Return true if there was no error, false if there was an error.
function checkForDisallowedESSymbolOperand(operator: SyntaxKind): boolean {
let offendingSymbolOperand =
someConstituentTypeHasKind(leftType, TypeFlags.ESSymbol) ? node.left :
someConstituentTypeHasKind(rightType, TypeFlags.ESSymbol) ? node.right :
someConstituentTypeHasKind(leftType, TypeFlags.ESSymbol) ? left :
someConstituentTypeHasKind(rightType, TypeFlags.ESSymbol) ? right :
undefined;
if (offendingSymbolOperand) {
error(offendingSymbolOperand, Diagnostics.The_0_operator_cannot_be_applied_to_type_symbol, tokenToString(operator));
@ -10192,17 +10216,17 @@ namespace ts {
// requires VarExpr to be classified as a reference
// A compound assignment furthermore requires VarExpr to be classified as a reference (section 4.1)
// and the type of the non - compound operation to be assignable to the type of VarExpr.
let ok = checkReferenceExpression(node.left, Diagnostics.Invalid_left_hand_side_of_assignment_expression, Diagnostics.Left_hand_side_of_assignment_expression_cannot_be_a_constant);
let ok = checkReferenceExpression(left, Diagnostics.Invalid_left_hand_side_of_assignment_expression, Diagnostics.Left_hand_side_of_assignment_expression_cannot_be_a_constant);
// Use default messages
if (ok) {
// to avoid cascading errors check assignability only if 'isReference' check succeeded and no errors were reported
checkTypeAssignableTo(valueType, leftType, node.left, /*headMessage*/ undefined);
checkTypeAssignableTo(valueType, leftType, left, /*headMessage*/ undefined);
}
}
}
function reportOperatorError() {
error(node, Diagnostics.Operator_0_cannot_be_applied_to_types_1_and_2, tokenToString(node.operatorToken.kind), typeToString(leftType), typeToString(rightType));
error(errorNode || operatorToken, Diagnostics.Operator_0_cannot_be_applied_to_types_1_and_2, tokenToString(operatorToken.kind), typeToString(leftType), typeToString(rightType));
}
}
@ -15434,7 +15458,7 @@ namespace ts {
}
}
function checkGrammarObjectLiteralExpression(node: ObjectLiteralExpression) {
function checkGrammarObjectLiteralExpression(node: ObjectLiteralExpression, inDestructuring: boolean) {
let seen: Map<SymbolFlags> = {};
let Property = 1;
let GetAccessor = 2;
@ -15450,6 +15474,12 @@ namespace ts {
continue;
}
if (prop.kind === SyntaxKind.ShorthandPropertyAssignment && !inDestructuring && (<ShorthandPropertyAssignment>prop).objectAssignmentInitializer) {
// having objectAssignmentInitializer is only valid in ObjectAssignmentPattern
// outside of destructuring it is a syntax error
return grammarErrorOnNode((<ShorthandPropertyAssignment>prop).equalsToken, Diagnostics.can_only_be_used_in_object_literal_properties_inside_destructuring_assignment);
}
// ECMA-262 11.1.5 Object Initialiser
// If previous is not undefined then throw a SyntaxError exception if any of the following conditions are true
// a.This production is contained in strict code and IsDataDescriptor(previous) is true and

View file

@ -800,6 +800,10 @@
"category": "Error",
"code": 1311
},
"'=' can only be used in object literal properties inside destructuring assignment.": {
"category": "Error",
"code": 1312
},
"Duplicate identifier '{0}'.": {
"category": "Error",
"code": 2300

View file

@ -2311,6 +2311,11 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
write(": ");
emit(node.name);
}
if (languageVersion >= ScriptTarget.ES6 && node.objectAssignmentInitializer) {
write(" = ");
emit(node.objectAssignmentInitializer);
}
}
function tryEmitConstantValue(node: PropertyAccessExpression | ElementAccessExpression): boolean {
@ -3574,7 +3579,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
for (let p of properties) {
if (p.kind === SyntaxKind.PropertyAssignment || p.kind === SyntaxKind.ShorthandPropertyAssignment) {
let propName = <Identifier | LiteralExpression>(<PropertyAssignment>p).name;
emitDestructuringAssignment((<PropertyAssignment>p).initializer || propName, createPropertyAccessForDestructuringProperty(value, propName));
let target = p.kind === SyntaxKind.ShorthandPropertyAssignment ? <ShorthandPropertyAssignment>p : (<PropertyAssignment>p).initializer || propName;
emitDestructuringAssignment(target, createPropertyAccessForDestructuringProperty(value, propName));
}
}
}
@ -3599,8 +3605,14 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
}
}
function emitDestructuringAssignment(target: Expression, value: Expression) {
if (target.kind === SyntaxKind.BinaryExpression && (<BinaryExpression>target).operatorToken.kind === SyntaxKind.EqualsToken) {
function emitDestructuringAssignment(target: Expression | ShorthandPropertyAssignment, value: Expression) {
if (target.kind === SyntaxKind.ShorthandPropertyAssignment) {
if ((<ShorthandPropertyAssignment>target).objectAssignmentInitializer) {
value = createDefaultValueCheck(value, (<ShorthandPropertyAssignment>target).objectAssignmentInitializer);
}
target = (<ShorthandPropertyAssignment>target).name;
}
else if (target.kind === SyntaxKind.BinaryExpression && (<BinaryExpression>target).operatorToken.kind === SyntaxKind.EqualsToken) {
value = createDefaultValueCheck(value, (<BinaryExpression>target).right);
target = (<BinaryExpression>target).left;
}

View file

@ -57,11 +57,17 @@ namespace ts {
return visitNode(cbNode, (<TypeParameterDeclaration>node).name) ||
visitNode(cbNode, (<TypeParameterDeclaration>node).constraint) ||
visitNode(cbNode, (<TypeParameterDeclaration>node).expression);
case SyntaxKind.ShorthandPropertyAssignment:
return visitNodes(cbNodes, node.decorators) ||
visitNodes(cbNodes, node.modifiers) ||
visitNode(cbNode, (<ShorthandPropertyAssignment>node).name) ||
visitNode(cbNode, (<ShorthandPropertyAssignment>node).questionToken) ||
visitNode(cbNode, (<ShorthandPropertyAssignment>node).equalsToken) ||
visitNode(cbNode, (<ShorthandPropertyAssignment>node).objectAssignmentInitializer);
case SyntaxKind.Parameter:
case SyntaxKind.PropertyDeclaration:
case SyntaxKind.PropertySignature:
case SyntaxKind.PropertyAssignment:
case SyntaxKind.ShorthandPropertyAssignment:
case SyntaxKind.VariableDeclaration:
case SyntaxKind.BindingElement:
return visitNodes(cbNodes, node.decorators) ||
@ -3758,11 +3764,23 @@ namespace ts {
return parseMethodDeclaration(fullStart, decorators, modifiers, asteriskToken, propertyName, questionToken);
}
// Parse to check if it is short-hand property assignment or normal property assignment
if ((token === SyntaxKind.CommaToken || token === SyntaxKind.CloseBraceToken) && tokenIsIdentifier) {
// check if it is short-hand property assignment or normal property assignment
// NOTE: if token is EqualsToken it is interpreted as CoverInitializedName production
// CoverInitializedName[Yield] :
// IdentifierReference[?Yield] Initializer[In, ?Yield]
// this is necessary because ObjectLiteral productions are also used to cover grammar for ObjectAssignmentPattern
const isShorthandPropertyAssignment =
tokenIsIdentifier && (token === SyntaxKind.CommaToken || token === SyntaxKind.CloseBraceToken || token === SyntaxKind.EqualsToken);
if (isShorthandPropertyAssignment) {
let shorthandDeclaration = <ShorthandPropertyAssignment>createNode(SyntaxKind.ShorthandPropertyAssignment, fullStart);
shorthandDeclaration.name = <Identifier>propertyName;
shorthandDeclaration.questionToken = questionToken;
const equalsToken = parseOptionalToken(SyntaxKind.EqualsToken);
if (equalsToken) {
shorthandDeclaration.equalsToken = equalsToken;
shorthandDeclaration.objectAssignmentInitializer = allowInAnd(parseAssignmentExpressionOrHigher);
}
return finishNode(shorthandDeclaration);
}
else {

View file

@ -562,6 +562,10 @@ namespace ts {
export interface ShorthandPropertyAssignment extends ObjectLiteralElement {
name: Identifier;
questionToken?: Node;
// used when ObjectLiteralExpression is used in ObjectAssignmentPattern
// it is grammar error to appear in actual object initializer
equalsToken?: Node;
objectAssignmentInitializer?: Expression;
}
// SyntaxKind.VariableDeclaration

View file

@ -1,4 +1,4 @@
tests/cases/conformance/es6/for-ofStatements/for-of48.ts(4,12): error TS1005: ':' expected.
tests/cases/conformance/es6/for-ofStatements/for-of48.ts(4,10): error TS2322: Type 'boolean' is not assignable to type 'number'.
==== tests/cases/conformance/es6/for-ofStatements/for-of48.ts (1 errors) ====
@ -6,8 +6,8 @@ tests/cases/conformance/es6/for-ofStatements/for-of48.ts(4,12): error TS1005: ':
var array = [{ x: "", y: true }]
enum E { x }
for ({x, y = E.x} of array) {
~
!!! error TS1005: ':' expected.
~
!!! error TS2322: Type 'boolean' is not assignable to type 'number'.
x;
y;
}

View file

@ -14,7 +14,7 @@ var E;
(function (E) {
E[E["x"] = 0] = "x";
})(E || (E = {}));
for ({ x, y: = E.x } of array) {
for ({ x, y = E.x } of array) {
x;
y;
}

View file

@ -0,0 +1,164 @@
tests/cases/compiler/shorthandPropertyAssignmentsInDestructuring.ts(16,9): error TS2459: Type '{}' has no property 's1' and no string index signature.
tests/cases/compiler/shorthandPropertyAssignmentsInDestructuring.ts(22,9): error TS2459: Type '{}' has no property 's1' and no string index signature.
tests/cases/compiler/shorthandPropertyAssignmentsInDestructuring.ts(40,9): error TS2322: Type 'number' is not assignable to type 'string'.
tests/cases/compiler/shorthandPropertyAssignmentsInDestructuring.ts(46,12): error TS2322: Type 'number' is not assignable to type 'string'.
tests/cases/compiler/shorthandPropertyAssignmentsInDestructuring.ts(72,5): error TS2322: Type 'number' is not assignable to type 'string'.
tests/cases/compiler/shorthandPropertyAssignmentsInDestructuring.ts(77,8): error TS2322: Type 'number' is not assignable to type 'string'.
tests/cases/compiler/shorthandPropertyAssignmentsInDestructuring.ts(82,5): error TS2322: Type 'number' is not assignable to type 'string'.
tests/cases/compiler/shorthandPropertyAssignmentsInDestructuring.ts(82,13): error TS2322: Type '{ x: number; }' is not assignable to type '{ x: string; }'.
Types of property 'x' are incompatible.
Type 'number' is not assignable to type 'string'.
tests/cases/compiler/shorthandPropertyAssignmentsInDestructuring.ts(87,8): error TS2322: Type 'number' is not assignable to type 'string'.
tests/cases/compiler/shorthandPropertyAssignmentsInDestructuring.ts(87,19): error TS2322: Type '{ x: number; }' is not assignable to type '{ x: string; }'.
Types of property 'x' are incompatible.
Type 'number' is not assignable to type 'string'.
tests/cases/compiler/shorthandPropertyAssignmentsInDestructuring.ts(113,12): error TS2304: Cannot find name 's'.
tests/cases/compiler/shorthandPropertyAssignmentsInDestructuring.ts(113,14): error TS1312: '=' can only be used in object literal properties inside destructuring assignment.
==== tests/cases/compiler/shorthandPropertyAssignmentsInDestructuring.ts (12 errors) ====
(function() {
var s0;
for ({ s0 = 5 } of [{ s0: 1 }]) {
}
});
(function() {
var s0;
for ({ s0:s0 = 5 } of [{ s0: 1 }]) {
}
});
(function() {
var s1;
for ({ s1 = 5 } of [{}]) {
~~
!!! error TS2459: Type '{}' has no property 's1' and no string index signature.
}
});
(function() {
var s1;
for ({ s1:s1 = 5 } of [{}]) {
~~
!!! error TS2459: Type '{}' has no property 's1' and no string index signature.
}
});
(function() {
var s2;
for ({ s2 = 5 } of [{ s2: "" }]) {
}
});
(function() {
var s2;
for ({ s2:s2 = 5 } of [{ s2: "" }]) {
}
});
(function() {
var s3: string;
for ({ s3 = 5 } of [{ s3: "" }]) {
~~
!!! error TS2322: Type 'number' is not assignable to type 'string'.
}
});
(function() {
var s3: string;
for ({ s3:s3 = 5 } of [{ s3: "" }]) {
~~
!!! error TS2322: Type 'number' is not assignable to type 'string'.
}
});
(function() {
let y;
({ y = 5 } = { y: 1 })
});
(function() {
let y;
({ y:y = 5 } = { y: 1 })
});
(function() {
let y0: number;
({ y0 = 5 } = { y0: 1 })
});
(function() {
let y0: number;
({ y0:y0 = 5 } = { y0: 1 })
});
(function() {
let y1: string;
({ y1 = 5 } = {})
~~
!!! error TS2322: Type 'number' is not assignable to type 'string'.
});
(function() {
let y1: string;
({ y1:y1 = 5 } = {})
~~
!!! error TS2322: Type 'number' is not assignable to type 'string'.
});
(function() {
let y2: string, y3: { x: string };
({ y2 = 5, y3 = { x: 1 } } = {})
~~
!!! error TS2322: Type 'number' is not assignable to type 'string'.
~~
!!! error TS2322: Type '{ x: number; }' is not assignable to type '{ x: string; }'.
!!! error TS2322: Types of property 'x' are incompatible.
!!! error TS2322: Type 'number' is not assignable to type 'string'.
});
(function() {
let y2: string, y3: { x: string };
({ y2:y2 = 5, y3:y3 = { x: 1 } } = {})
~~
!!! error TS2322: Type 'number' is not assignable to type 'string'.
~~
!!! error TS2322: Type '{ x: number; }' is not assignable to type '{ x: string; }'.
!!! error TS2322: Types of property 'x' are incompatible.
!!! error TS2322: Type 'number' is not assignable to type 'string'.
});
(function() {
let y4: number, y5: { x: number };
({ y4 = 5, y5 = { x: 1 } } = {})
});
(function() {
let y4: number, y5: { x: number };
({ y4:y4 = 5, y5:y5 = { x: 1 } } = {})
});
(function() {
let z;
({ z = { x: 5 } } = { z: { x: 1 } });
});
(function() {
let z;
({ z:z = { x: 5 } } = { z: { x: 1 } });
});
(function() {
let a = { s = 5 };
~
!!! error TS2304: Cannot find name 's'.
~
!!! error TS1312: '=' can only be used in object literal properties inside destructuring assignment.
});
function foo({a = 4, b = { x: 5 }}) {
}

View file

@ -0,0 +1,242 @@
//// [shorthandPropertyAssignmentsInDestructuring.ts]
(function() {
var s0;
for ({ s0 = 5 } of [{ s0: 1 }]) {
}
});
(function() {
var s0;
for ({ s0:s0 = 5 } of [{ s0: 1 }]) {
}
});
(function() {
var s1;
for ({ s1 = 5 } of [{}]) {
}
});
(function() {
var s1;
for ({ s1:s1 = 5 } of [{}]) {
}
});
(function() {
var s2;
for ({ s2 = 5 } of [{ s2: "" }]) {
}
});
(function() {
var s2;
for ({ s2:s2 = 5 } of [{ s2: "" }]) {
}
});
(function() {
var s3: string;
for ({ s3 = 5 } of [{ s3: "" }]) {
}
});
(function() {
var s3: string;
for ({ s3:s3 = 5 } of [{ s3: "" }]) {
}
});
(function() {
let y;
({ y = 5 } = { y: 1 })
});
(function() {
let y;
({ y:y = 5 } = { y: 1 })
});
(function() {
let y0: number;
({ y0 = 5 } = { y0: 1 })
});
(function() {
let y0: number;
({ y0:y0 = 5 } = { y0: 1 })
});
(function() {
let y1: string;
({ y1 = 5 } = {})
});
(function() {
let y1: string;
({ y1:y1 = 5 } = {})
});
(function() {
let y2: string, y3: { x: string };
({ y2 = 5, y3 = { x: 1 } } = {})
});
(function() {
let y2: string, y3: { x: string };
({ y2:y2 = 5, y3:y3 = { x: 1 } } = {})
});
(function() {
let y4: number, y5: { x: number };
({ y4 = 5, y5 = { x: 1 } } = {})
});
(function() {
let y4: number, y5: { x: number };
({ y4:y4 = 5, y5:y5 = { x: 1 } } = {})
});
(function() {
let z;
({ z = { x: 5 } } = { z: { x: 1 } });
});
(function() {
let z;
({ z:z = { x: 5 } } = { z: { x: 1 } });
});
(function() {
let a = { s = 5 };
});
function foo({a = 4, b = { x: 5 }}) {
}
//// [shorthandPropertyAssignmentsInDestructuring.js]
(function () {
var s0;
for (var _i = 0, _a = [{ s0: 1 }]; _i < _a.length; _i++) {
_b = _a[_i].s0, s0 = _b === void 0 ? 5 : _b;
}
var _b;
});
(function () {
var s0;
for (var _i = 0, _a = [{ s0: 1 }]; _i < _a.length; _i++) {
_b = _a[_i].s0, s0 = _b === void 0 ? 5 : _b;
}
var _b;
});
(function () {
var s1;
for (var _i = 0, _a = [{}]; _i < _a.length; _i++) {
_b = _a[_i].s1, s1 = _b === void 0 ? 5 : _b;
}
var _b;
});
(function () {
var s1;
for (var _i = 0, _a = [{}]; _i < _a.length; _i++) {
_b = _a[_i].s1, s1 = _b === void 0 ? 5 : _b;
}
var _b;
});
(function () {
var s2;
for (var _i = 0, _a = [{ s2: "" }]; _i < _a.length; _i++) {
_b = _a[_i].s2, s2 = _b === void 0 ? 5 : _b;
}
var _b;
});
(function () {
var s2;
for (var _i = 0, _a = [{ s2: "" }]; _i < _a.length; _i++) {
_b = _a[_i].s2, s2 = _b === void 0 ? 5 : _b;
}
var _b;
});
(function () {
var s3;
for (var _i = 0, _a = [{ s3: "" }]; _i < _a.length; _i++) {
_b = _a[_i].s3, s3 = _b === void 0 ? 5 : _b;
}
var _b;
});
(function () {
var s3;
for (var _i = 0, _a = [{ s3: "" }]; _i < _a.length; _i++) {
_b = _a[_i].s3, s3 = _b === void 0 ? 5 : _b;
}
var _b;
});
(function () {
var y;
(_a = { y: 1 }, _b = _a.y, y = _b === void 0 ? 5 : _b, _a);
var _a, _b;
});
(function () {
var y;
(_a = { y: 1 }, _b = _a.y, y = _b === void 0 ? 5 : _b, _a);
var _a, _b;
});
(function () {
var y0;
(_a = { y0: 1 }, _b = _a.y0, y0 = _b === void 0 ? 5 : _b, _a);
var _a, _b;
});
(function () {
var y0;
(_a = { y0: 1 }, _b = _a.y0, y0 = _b === void 0 ? 5 : _b, _a);
var _a, _b;
});
(function () {
var y1;
(_a = {}, _b = _a.y1, y1 = _b === void 0 ? 5 : _b, _a);
var _a, _b;
});
(function () {
var y1;
(_a = {}, _b = _a.y1, y1 = _b === void 0 ? 5 : _b, _a);
var _a, _b;
});
(function () {
var y2, y3;
(_a = {}, _b = _a.y2, y2 = _b === void 0 ? 5 : _b, _c = _a.y3, y3 = _c === void 0 ? { x: 1 } : _c, _a);
var _a, _b, _c;
});
(function () {
var y2, y3;
(_a = {}, _b = _a.y2, y2 = _b === void 0 ? 5 : _b, _c = _a.y3, y3 = _c === void 0 ? { x: 1 } : _c, _a);
var _a, _b, _c;
});
(function () {
var y4, y5;
(_a = {}, _b = _a.y4, y4 = _b === void 0 ? 5 : _b, _c = _a.y5, y5 = _c === void 0 ? { x: 1 } : _c, _a);
var _a, _b, _c;
});
(function () {
var y4, y5;
(_a = {}, _b = _a.y4, y4 = _b === void 0 ? 5 : _b, _c = _a.y5, y5 = _c === void 0 ? { x: 1 } : _c, _a);
var _a, _b, _c;
});
(function () {
var z;
(_a = { z: { x: 1 } }, _b = _a.z, z = _b === void 0 ? { x: 5 } : _b, _a);
var _a, _b;
});
(function () {
var z;
(_a = { z: { x: 1 } }, _b = _a.z, z = _b === void 0 ? { x: 5 } : _b, _a);
var _a, _b;
});
(function () {
var a = { s: s };
});
function foo(_a) {
var _b = _a.a, a = _b === void 0 ? 4 : _b, _c = _a.b, b = _c === void 0 ? { x: 5 } : _c;
}

View file

@ -0,0 +1,164 @@
tests/cases/compiler/shorthandPropertyAssignmentsInDestructuring_ES6.ts(16,9): error TS2459: Type '{}' has no property 's1' and no string index signature.
tests/cases/compiler/shorthandPropertyAssignmentsInDestructuring_ES6.ts(22,9): error TS2459: Type '{}' has no property 's1' and no string index signature.
tests/cases/compiler/shorthandPropertyAssignmentsInDestructuring_ES6.ts(40,9): error TS2322: Type 'number' is not assignable to type 'string'.
tests/cases/compiler/shorthandPropertyAssignmentsInDestructuring_ES6.ts(46,12): error TS2322: Type 'number' is not assignable to type 'string'.
tests/cases/compiler/shorthandPropertyAssignmentsInDestructuring_ES6.ts(72,5): error TS2322: Type 'number' is not assignable to type 'string'.
tests/cases/compiler/shorthandPropertyAssignmentsInDestructuring_ES6.ts(77,8): error TS2322: Type 'number' is not assignable to type 'string'.
tests/cases/compiler/shorthandPropertyAssignmentsInDestructuring_ES6.ts(82,5): error TS2322: Type 'number' is not assignable to type 'string'.
tests/cases/compiler/shorthandPropertyAssignmentsInDestructuring_ES6.ts(82,13): error TS2322: Type '{ x: number; }' is not assignable to type '{ x: string; }'.
Types of property 'x' are incompatible.
Type 'number' is not assignable to type 'string'.
tests/cases/compiler/shorthandPropertyAssignmentsInDestructuring_ES6.ts(87,8): error TS2322: Type 'number' is not assignable to type 'string'.
tests/cases/compiler/shorthandPropertyAssignmentsInDestructuring_ES6.ts(87,19): error TS2322: Type '{ x: number; }' is not assignable to type '{ x: string; }'.
Types of property 'x' are incompatible.
Type 'number' is not assignable to type 'string'.
tests/cases/compiler/shorthandPropertyAssignmentsInDestructuring_ES6.ts(113,12): error TS2304: Cannot find name 's'.
tests/cases/compiler/shorthandPropertyAssignmentsInDestructuring_ES6.ts(113,14): error TS1312: '=' can only be used in object literal properties inside destructuring assignment.
==== tests/cases/compiler/shorthandPropertyAssignmentsInDestructuring_ES6.ts (12 errors) ====
(function() {
var s0;
for ({ s0 = 5 } of [{ s0: 1 }]) {
}
});
(function() {
var s0;
for ({ s0:s0 = 5 } of [{ s0: 1 }]) {
}
});
(function() {
var s1;
for ({ s1 = 5 } of [{}]) {
~~
!!! error TS2459: Type '{}' has no property 's1' and no string index signature.
}
});
(function() {
var s1;
for ({ s1:s1 = 5 } of [{}]) {
~~
!!! error TS2459: Type '{}' has no property 's1' and no string index signature.
}
});
(function() {
var s2;
for ({ s2 = 5 } of [{ s2: "" }]) {
}
});
(function() {
var s2;
for ({ s2:s2 = 5 } of [{ s2: "" }]) {
}
});
(function() {
var s3: string;
for ({ s3 = 5 } of [{ s3: "" }]) {
~~
!!! error TS2322: Type 'number' is not assignable to type 'string'.
}
});
(function() {
var s3: string;
for ({ s3:s3 = 5 } of [{ s3: "" }]) {
~~
!!! error TS2322: Type 'number' is not assignable to type 'string'.
}
});
(function() {
let y;
({ y = 5 } = { y: 1 })
});
(function() {
let y;
({ y:y = 5 } = { y: 1 })
});
(function() {
let y0: number;
({ y0 = 5 } = { y0: 1 })
});
(function() {
let y0: number;
({ y0:y0 = 5 } = { y0: 1 })
});
(function() {
let y1: string;
({ y1 = 5 } = {})
~~
!!! error TS2322: Type 'number' is not assignable to type 'string'.
});
(function() {
let y1: string;
({ y1:y1 = 5 } = {})
~~
!!! error TS2322: Type 'number' is not assignable to type 'string'.
});
(function() {
let y2: string, y3: { x: string };
({ y2 = 5, y3 = { x: 1 } } = {})
~~
!!! error TS2322: Type 'number' is not assignable to type 'string'.
~~
!!! error TS2322: Type '{ x: number; }' is not assignable to type '{ x: string; }'.
!!! error TS2322: Types of property 'x' are incompatible.
!!! error TS2322: Type 'number' is not assignable to type 'string'.
});
(function() {
let y2: string, y3: { x: string };
({ y2:y2 = 5, y3:y3 = { x: 1 } } = {})
~~
!!! error TS2322: Type 'number' is not assignable to type 'string'.
~~
!!! error TS2322: Type '{ x: number; }' is not assignable to type '{ x: string; }'.
!!! error TS2322: Types of property 'x' are incompatible.
!!! error TS2322: Type 'number' is not assignable to type 'string'.
});
(function() {
let y4: number, y5: { x: number };
({ y4 = 5, y5 = { x: 1 } } = {})
});
(function() {
let y4: number, y5: { x: number };
({ y4:y4 = 5, y5:y5 = { x: 1 } } = {})
});
(function() {
let z;
({ z = { x: 5 } } = { z: { x: 1 } });
});
(function() {
let z;
({ z:z = { x: 5 } } = { z: { x: 1 } });
});
(function() {
let a = { s = 5 };
~
!!! error TS2304: Cannot find name 's'.
~
!!! error TS1312: '=' can only be used in object literal properties inside destructuring assignment.
});
function foo({a = 4, b = { x: 5 }}) {
}

View file

@ -0,0 +1,213 @@
//// [shorthandPropertyAssignmentsInDestructuring_ES6.ts]
(function() {
var s0;
for ({ s0 = 5 } of [{ s0: 1 }]) {
}
});
(function() {
var s0;
for ({ s0:s0 = 5 } of [{ s0: 1 }]) {
}
});
(function() {
var s1;
for ({ s1 = 5 } of [{}]) {
}
});
(function() {
var s1;
for ({ s1:s1 = 5 } of [{}]) {
}
});
(function() {
var s2;
for ({ s2 = 5 } of [{ s2: "" }]) {
}
});
(function() {
var s2;
for ({ s2:s2 = 5 } of [{ s2: "" }]) {
}
});
(function() {
var s3: string;
for ({ s3 = 5 } of [{ s3: "" }]) {
}
});
(function() {
var s3: string;
for ({ s3:s3 = 5 } of [{ s3: "" }]) {
}
});
(function() {
let y;
({ y = 5 } = { y: 1 })
});
(function() {
let y;
({ y:y = 5 } = { y: 1 })
});
(function() {
let y0: number;
({ y0 = 5 } = { y0: 1 })
});
(function() {
let y0: number;
({ y0:y0 = 5 } = { y0: 1 })
});
(function() {
let y1: string;
({ y1 = 5 } = {})
});
(function() {
let y1: string;
({ y1:y1 = 5 } = {})
});
(function() {
let y2: string, y3: { x: string };
({ y2 = 5, y3 = { x: 1 } } = {})
});
(function() {
let y2: string, y3: { x: string };
({ y2:y2 = 5, y3:y3 = { x: 1 } } = {})
});
(function() {
let y4: number, y5: { x: number };
({ y4 = 5, y5 = { x: 1 } } = {})
});
(function() {
let y4: number, y5: { x: number };
({ y4:y4 = 5, y5:y5 = { x: 1 } } = {})
});
(function() {
let z;
({ z = { x: 5 } } = { z: { x: 1 } });
});
(function() {
let z;
({ z:z = { x: 5 } } = { z: { x: 1 } });
});
(function() {
let a = { s = 5 };
});
function foo({a = 4, b = { x: 5 }}) {
}
//// [shorthandPropertyAssignmentsInDestructuring_ES6.js]
(function () {
var s0;
for ({ s0 = 5 } of [{ s0: 1 }]) {
}
});
(function () {
var s0;
for ({ s0: s0 = 5 } of [{ s0: 1 }]) {
}
});
(function () {
var s1;
for ({ s1 = 5 } of [{}]) {
}
});
(function () {
var s1;
for ({ s1: s1 = 5 } of [{}]) {
}
});
(function () {
var s2;
for ({ s2 = 5 } of [{ s2: "" }]) {
}
});
(function () {
var s2;
for ({ s2: s2 = 5 } of [{ s2: "" }]) {
}
});
(function () {
var s3;
for ({ s3 = 5 } of [{ s3: "" }]) {
}
});
(function () {
var s3;
for ({ s3: s3 = 5 } of [{ s3: "" }]) {
}
});
(function () {
let y;
({ y = 5 } = { y: 1 });
});
(function () {
let y;
({ y: y = 5 } = { y: 1 });
});
(function () {
let y0;
({ y0 = 5 } = { y0: 1 });
});
(function () {
let y0;
({ y0: y0 = 5 } = { y0: 1 });
});
(function () {
let y1;
({ y1 = 5 } = {});
});
(function () {
let y1;
({ y1: y1 = 5 } = {});
});
(function () {
let y2, y3;
({ y2 = 5, y3 = { x: 1 } } = {});
});
(function () {
let y2, y3;
({ y2: y2 = 5, y3: y3 = { x: 1 } } = {});
});
(function () {
let y4, y5;
({ y4 = 5, y5 = { x: 1 } } = {});
});
(function () {
let y4, y5;
({ y4: y4 = 5, y5: y5 = { x: 1 } } = {});
});
(function () {
let z;
({ z = { x: 5 } } = { z: { x: 1 } });
});
(function () {
let z;
({ z: z = { x: 5 } } = { z: { x: 1 } });
});
(function () {
let a = { s = 5 };
});
function foo({ a = 4, b = { x: 5 } }) {
}

View file

@ -0,0 +1,118 @@
// @target: ES5
(function() {
var s0;
for ({ s0 = 5 } of [{ s0: 1 }]) {
}
});
(function() {
var s0;
for ({ s0:s0 = 5 } of [{ s0: 1 }]) {
}
});
(function() {
var s1;
for ({ s1 = 5 } of [{}]) {
}
});
(function() {
var s1;
for ({ s1:s1 = 5 } of [{}]) {
}
});
(function() {
var s2;
for ({ s2 = 5 } of [{ s2: "" }]) {
}
});
(function() {
var s2;
for ({ s2:s2 = 5 } of [{ s2: "" }]) {
}
});
(function() {
var s3: string;
for ({ s3 = 5 } of [{ s3: "" }]) {
}
});
(function() {
var s3: string;
for ({ s3:s3 = 5 } of [{ s3: "" }]) {
}
});
(function() {
let y;
({ y = 5 } = { y: 1 })
});
(function() {
let y;
({ y:y = 5 } = { y: 1 })
});
(function() {
let y0: number;
({ y0 = 5 } = { y0: 1 })
});
(function() {
let y0: number;
({ y0:y0 = 5 } = { y0: 1 })
});
(function() {
let y1: string;
({ y1 = 5 } = {})
});
(function() {
let y1: string;
({ y1:y1 = 5 } = {})
});
(function() {
let y2: string, y3: { x: string };
({ y2 = 5, y3 = { x: 1 } } = {})
});
(function() {
let y2: string, y3: { x: string };
({ y2:y2 = 5, y3:y3 = { x: 1 } } = {})
});
(function() {
let y4: number, y5: { x: number };
({ y4 = 5, y5 = { x: 1 } } = {})
});
(function() {
let y4: number, y5: { x: number };
({ y4:y4 = 5, y5:y5 = { x: 1 } } = {})
});
(function() {
let z;
({ z = { x: 5 } } = { z: { x: 1 } });
});
(function() {
let z;
({ z:z = { x: 5 } } = { z: { x: 1 } });
});
(function() {
let a = { s = 5 };
});
function foo({a = 4, b = { x: 5 }}) {
}

View file

@ -0,0 +1,118 @@
// @target: ES6
(function() {
var s0;
for ({ s0 = 5 } of [{ s0: 1 }]) {
}
});
(function() {
var s0;
for ({ s0:s0 = 5 } of [{ s0: 1 }]) {
}
});
(function() {
var s1;
for ({ s1 = 5 } of [{}]) {
}
});
(function() {
var s1;
for ({ s1:s1 = 5 } of [{}]) {
}
});
(function() {
var s2;
for ({ s2 = 5 } of [{ s2: "" }]) {
}
});
(function() {
var s2;
for ({ s2:s2 = 5 } of [{ s2: "" }]) {
}
});
(function() {
var s3: string;
for ({ s3 = 5 } of [{ s3: "" }]) {
}
});
(function() {
var s3: string;
for ({ s3:s3 = 5 } of [{ s3: "" }]) {
}
});
(function() {
let y;
({ y = 5 } = { y: 1 })
});
(function() {
let y;
({ y:y = 5 } = { y: 1 })
});
(function() {
let y0: number;
({ y0 = 5 } = { y0: 1 })
});
(function() {
let y0: number;
({ y0:y0 = 5 } = { y0: 1 })
});
(function() {
let y1: string;
({ y1 = 5 } = {})
});
(function() {
let y1: string;
({ y1:y1 = 5 } = {})
});
(function() {
let y2: string, y3: { x: string };
({ y2 = 5, y3 = { x: 1 } } = {})
});
(function() {
let y2: string, y3: { x: string };
({ y2:y2 = 5, y3:y3 = { x: 1 } } = {})
});
(function() {
let y4: number, y5: { x: number };
({ y4 = 5, y5 = { x: 1 } } = {})
});
(function() {
let y4: number, y5: { x: number };
({ y4:y4 = 5, y5:y5 = { x: 1 } } = {})
});
(function() {
let z;
({ z = { x: 5 } } = { z: { x: 1 } });
});
(function() {
let z;
({ z:z = { x: 5 } } = { z: { x: 1 } });
});
(function() {
let a = { s = 5 };
});
function foo({a = 4, b = { x: 5 }}) {
}