mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-24 11:43:18 -05:00
Merge pull request #12310 from Microsoft/check-object-rest-destructuring-assignment
Check object rest destructuring assignment
This commit is contained in:
@@ -14265,12 +14265,13 @@ namespace ts {
|
||||
function checkObjectLiteralAssignment(node: ObjectLiteralExpression, sourceType: Type): Type {
|
||||
const properties = node.properties;
|
||||
for (const p of properties) {
|
||||
checkObjectLiteralDestructuringPropertyAssignment(sourceType, p);
|
||||
checkObjectLiteralDestructuringPropertyAssignment(sourceType, p, properties);
|
||||
}
|
||||
return sourceType;
|
||||
}
|
||||
|
||||
function checkObjectLiteralDestructuringPropertyAssignment(objectLiteralType: Type, property: ObjectLiteralElementLike) {
|
||||
/** Note: If property cannot be a SpreadAssignment, then allProperties does not need to be provided */
|
||||
function checkObjectLiteralDestructuringPropertyAssignment(objectLiteralType: Type, property: ObjectLiteralElementLike, allProperties?: ObjectLiteralElementLike[]) {
|
||||
if (property.kind === SyntaxKind.PropertyAssignment || property.kind === SyntaxKind.ShorthandPropertyAssignment) {
|
||||
const name = <PropertyName>(<PropertyAssignment>property).name;
|
||||
if (name.kind === SyntaxKind.ComputedPropertyName) {
|
||||
@@ -14300,7 +14301,14 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
else if (property.kind === SyntaxKind.SpreadAssignment) {
|
||||
checkReferenceExpression(property.expression, Diagnostics.The_target_of_an_object_rest_assignment_must_be_a_variable_or_a_property_access);
|
||||
const nonRestNames: PropertyName[] = [];
|
||||
if (allProperties) {
|
||||
for (let i = 0; i < allProperties.length - 1; i++) {
|
||||
nonRestNames.push(allProperties[i].name);
|
||||
}
|
||||
}
|
||||
const type = getRestType(objectLiteralType, nonRestNames, objectLiteralType.symbol);
|
||||
return checkDestructuringAssignment(property.expression, type);
|
||||
}
|
||||
else {
|
||||
error(property, Diagnostics.Property_assignment_expected);
|
||||
@@ -14398,7 +14406,10 @@ namespace ts {
|
||||
|
||||
function checkReferenceAssignment(target: Expression, sourceType: Type, contextualMapper?: TypeMapper): Type {
|
||||
const targetType = checkExpression(target, contextualMapper);
|
||||
if (checkReferenceExpression(target, Diagnostics.The_left_hand_side_of_an_assignment_expression_must_be_a_variable_or_a_property_access)) {
|
||||
const error = target.parent.kind === SyntaxKind.SpreadAssignment ?
|
||||
Diagnostics.The_target_of_an_object_rest_assignment_must_be_a_variable_or_a_property_access :
|
||||
Diagnostics.The_left_hand_side_of_an_assignment_expression_must_be_a_variable_or_a_property_access;
|
||||
if (checkReferenceExpression(target, error)) {
|
||||
checkTypeAssignableTo(sourceType, targetType, target, /*headMessage*/ undefined);
|
||||
}
|
||||
return sourceType;
|
||||
|
||||
@@ -1,14 +1,27 @@
|
||||
tests/cases/conformance/types/rest/objectRestNegative.ts(2,10): error TS2462: A rest element must be last in a destructuring pattern
|
||||
tests/cases/conformance/types/rest/objectRestNegative.ts(3,31): error TS2462: A rest element must be last in a destructuring pattern
|
||||
tests/cases/conformance/types/rest/objectRestNegative.ts(6,17): error TS2700: Rest types may only be created from object types.
|
||||
tests/cases/conformance/types/rest/objectRestNegative.ts(11,9): error TS2701: The target of an object rest assignment must be a variable or a property access.
|
||||
tests/cases/conformance/types/rest/objectRestNegative.ts(6,10): error TS2322: Type '{ a: number; }' is not assignable to type '{ a: string; }'.
|
||||
Types of property 'a' are incompatible.
|
||||
Type 'number' is not assignable to type 'string'.
|
||||
tests/cases/conformance/types/rest/objectRestNegative.ts(9,31): error TS2462: A rest element must be last in a destructuring pattern
|
||||
tests/cases/conformance/types/rest/objectRestNegative.ts(12,17): error TS2700: Rest types may only be created from object types.
|
||||
tests/cases/conformance/types/rest/objectRestNegative.ts(17,9): error TS2701: The target of an object rest assignment must be a variable or a property access.
|
||||
|
||||
|
||||
==== tests/cases/conformance/types/rest/objectRestNegative.ts (4 errors) ====
|
||||
==== tests/cases/conformance/types/rest/objectRestNegative.ts (5 errors) ====
|
||||
let o = { a: 1, b: 'no' };
|
||||
var { ...mustBeLast, a } = o;
|
||||
~~~~~~~~~~
|
||||
!!! error TS2462: A rest element must be last in a destructuring pattern
|
||||
|
||||
var b: string;
|
||||
let notAssignable: { a: string };
|
||||
({ b, ...notAssignable } = o);
|
||||
~~~~~~~~~~~~~
|
||||
!!! error TS2322: Type '{ a: number; }' is not assignable to type '{ a: string; }'.
|
||||
!!! error TS2322: Types of property 'a' are incompatible.
|
||||
!!! error TS2322: Type 'number' is not assignable to type 'string'.
|
||||
|
||||
|
||||
function stillMustBeLast({ ...mustBeLast, a }: { a: number, b: string }): void {
|
||||
~~~~~~~~~~
|
||||
!!! error TS2462: A rest element must be last in a destructuring pattern
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
//// [objectRestNegative.ts]
|
||||
let o = { a: 1, b: 'no' };
|
||||
var { ...mustBeLast, a } = o;
|
||||
|
||||
var b: string;
|
||||
let notAssignable: { a: string };
|
||||
({ b, ...notAssignable } = o);
|
||||
|
||||
|
||||
function stillMustBeLast({ ...mustBeLast, a }: { a: number, b: string }): void {
|
||||
}
|
||||
function generic<T extends { x, y }>(t: T) {
|
||||
@@ -24,6 +30,9 @@ var __rest = (this && this.__rest) || function (s, e) {
|
||||
};
|
||||
var o = { a: 1, b: 'no' };
|
||||
var a = o.a;
|
||||
var b;
|
||||
var notAssignable;
|
||||
(b = o.b, o, notAssignable = __rest(o, ["b"]));
|
||||
function stillMustBeLast(_a) {
|
||||
var a = _a.a;
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
const y = { a: 'yes', b: 'no' };
|
||||
const o = { x: 1, ...y };
|
||||
var b;
|
||||
var rest;
|
||||
var rest: any;
|
||||
({ b, ...rest } = o);
|
||||
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ const o = { x: 1, ...y };
|
||||
var b;
|
||||
>b : Symbol(b, Decl(objectSpreadNoTransform.ts, 2, 3))
|
||||
|
||||
var rest;
|
||||
var rest: any;
|
||||
>rest : Symbol(rest, Decl(objectSpreadNoTransform.ts, 3, 3))
|
||||
|
||||
({ b, ...rest } = o);
|
||||
|
||||
@@ -17,7 +17,7 @@ const o = { x: 1, ...y };
|
||||
var b;
|
||||
>b : any
|
||||
|
||||
var rest;
|
||||
var rest: any;
|
||||
>rest : any
|
||||
|
||||
({ b, ...rest } = o);
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
let o = { a: 1, b: 'no' };
|
||||
var { ...mustBeLast, a } = o;
|
||||
|
||||
var b: string;
|
||||
let notAssignable: { a: string };
|
||||
({ b, ...notAssignable } = o);
|
||||
|
||||
|
||||
function stillMustBeLast({ ...mustBeLast, a }: { a: number, b: string }): void {
|
||||
}
|
||||
function generic<T extends { x, y }>(t: T) {
|
||||
|
||||
@@ -2,5 +2,5 @@
|
||||
const y = { a: 'yes', b: 'no' };
|
||||
const o = { x: 1, ...y };
|
||||
var b;
|
||||
var rest;
|
||||
var rest: any;
|
||||
({ b, ...rest } = o);
|
||||
|
||||
Reference in New Issue
Block a user