do not report 'excess property error' if object literal pattern contains computed properties

This commit is contained in:
Vladimir Matveev
2015-11-07 16:56:16 -08:00
parent 572db9c403
commit 72723e93be
4 changed files with 15 additions and 77 deletions

View File

@@ -2500,10 +2500,12 @@ namespace ts {
// Return the type implied by an object binding pattern
function getTypeFromObjectBindingPattern(pattern: BindingPattern, includePatternInType: boolean): Type {
const members: SymbolTable = {};
let hasComputedProperties = false;
forEach(pattern.elements, e => {
const name = e.propertyName || <Identifier>e.name;
if (isComputedNonLiteralName(name)) {
// do not include computed properties in the implied type
hasComputedProperties = true;
return;
}
@@ -2518,6 +2520,9 @@ namespace ts {
if (includePatternInType) {
result.pattern = pattern;
}
if (hasComputedProperties) {
result.flags |= TypeFlags.ObjectLiteralPatternWithComputedProperties;
}
return result;
}
@@ -5010,7 +5015,7 @@ namespace ts {
}
function hasExcessProperties(source: FreshObjectLiteralType, target: Type, reportErrors: boolean): boolean {
if (someConstituentTypeHasKind(target, TypeFlags.ObjectType)) {
if (!(target.flags & TypeFlags.ObjectLiteralPatternWithComputedProperties) && someConstituentTypeHasKind(target, TypeFlags.ObjectType)) {
for (const prop of getPropertiesOfObjectType(source)) {
if (!isKnownProperty(target, prop.name)) {
if (reportErrors) {
@@ -7428,6 +7433,7 @@ namespace ts {
(contextualType.pattern.kind === SyntaxKind.ObjectBindingPattern || contextualType.pattern.kind === SyntaxKind.ObjectLiteralExpression);
let typeFlags: TypeFlags = 0;
let patternWithComputedProperties = false;
for (const memberDecl of node.properties) {
let member = memberDecl.symbol;
if (memberDecl.kind === SyntaxKind.PropertyAssignment ||
@@ -7455,8 +7461,11 @@ namespace ts {
if (isOptional) {
prop.flags |= SymbolFlags.Optional;
}
if (hasDynamicName(memberDecl)) {
patternWithComputedProperties = true;
}
}
else if (contextualTypeHasPattern) {
else if (contextualTypeHasPattern && !(contextualType.flags & TypeFlags.ObjectLiteralPatternWithComputedProperties)) {
// If object literal is contextually typed by the implied type of a binding pattern, and if the
// binding pattern specifies a default value for the property, make the property optional.
const impliedProp = getPropertyOfType(contextualType, member.name);
@@ -7513,7 +7522,7 @@ namespace ts {
const numberIndexType = getIndexType(IndexKind.Number);
const result = createAnonymousType(node.symbol, propertiesTable, emptyArray, emptyArray, stringIndexType, numberIndexType);
const freshObjectLiteralFlag = compilerOptions.suppressExcessPropertyErrors ? 0 : TypeFlags.FreshObjectLiteral;
result.flags |= TypeFlags.ObjectLiteral | TypeFlags.ContainsObjectLiteral | freshObjectLiteralFlag | (typeFlags & TypeFlags.PropagatingFlags);
result.flags |= TypeFlags.ObjectLiteral | TypeFlags.ContainsObjectLiteral | freshObjectLiteralFlag | (typeFlags & TypeFlags.PropagatingFlags) | (patternWithComputedProperties ? TypeFlags.ObjectLiteralPatternWithComputedProperties : 0);
if (inDestructuringPattern) {
result.pattern = node;
}

View File

@@ -1822,6 +1822,7 @@ namespace ts {
ContainsAnyFunctionType = 0x00800000, // Type is or contains object literal type
ESSymbol = 0x01000000, // Type of symbol primitive introduced in ES6
ThisType = 0x02000000, // This type
ObjectLiteralPatternWithComputedProperties = 0x04000000, // Object literal type implied by binding pattern has computed properties
/* @internal */
Intrinsic = Any | String | Number | Boolean | ESSymbol | Void | Undefined | Null,

View File

@@ -1,41 +1,21 @@
tests/cases/compiler/computedPropertiesInDestructuring1.ts(3,21): error TS2353: Object literal may only specify known properties, and 'bar' does not exist in type '{}'.
tests/cases/compiler/computedPropertiesInDestructuring1.ts(8,25): error TS2353: Object literal may only specify known properties, and 'bar' does not exist in type '{}'.
tests/cases/compiler/computedPropertiesInDestructuring1.ts(10,25): error TS2353: Object literal may only specify known properties, and 'bar' does not exist in type '{}'.
tests/cases/compiler/computedPropertiesInDestructuring1.ts(11,28): error TS2353: Object literal may only specify known properties, and 'bar' does not exist in type '{}'.
tests/cases/compiler/computedPropertiesInDestructuring1.ts(20,8): error TS2349: Cannot invoke an expression whose type lacks a call signature.
tests/cases/compiler/computedPropertiesInDestructuring1.ts(20,27): error TS2353: Object literal may only specify known properties, and 'bar' does not exist in type '{}'.
tests/cases/compiler/computedPropertiesInDestructuring1.ts(21,12): error TS2339: Property 'toExponential' does not exist on type 'string'.
tests/cases/compiler/computedPropertiesInDestructuring1.ts(21,41): error TS2353: Object literal may only specify known properties, and 'bar' does not exist in type '{}'.
tests/cases/compiler/computedPropertiesInDestructuring1.ts(24,18): error TS2353: Object literal may only specify known properties, and 'bar' does not exist in type '{}'.
tests/cases/compiler/computedPropertiesInDestructuring1.ts(28,22): error TS2353: Object literal may only specify known properties, and 'bar' does not exist in type '{}'.
tests/cases/compiler/computedPropertiesInDestructuring1.ts(30,21): error TS2353: Object literal may only specify known properties, and 'bar' does not exist in type '{}'.
tests/cases/compiler/computedPropertiesInDestructuring1.ts(31,24): error TS2353: Object literal may only specify known properties, and 'bar' does not exist in type '{}'.
tests/cases/compiler/computedPropertiesInDestructuring1.ts(33,4): error TS2349: Cannot invoke an expression whose type lacks a call signature.
tests/cases/compiler/computedPropertiesInDestructuring1.ts(33,23): error TS2353: Object literal may only specify known properties, and 'bar' does not exist in type '{}'.
tests/cases/compiler/computedPropertiesInDestructuring1.ts(34,5): error TS2365: Operator '+' cannot be applied to types 'number' and '{}'.
tests/cases/compiler/computedPropertiesInDestructuring1.ts(34,26): error TS2353: Object literal may only specify known properties, and 'bar' does not exist in type '{}'.
==== tests/cases/compiler/computedPropertiesInDestructuring1.ts (16 errors) ====
==== tests/cases/compiler/computedPropertiesInDestructuring1.ts (4 errors) ====
// destructuring in variable declarations
let foo = "bar";
let {[foo]: bar} = {bar: "bar"};
~~~
!!! error TS2353: Object literal may only specify known properties, and 'bar' does not exist in type '{}'.
let {["bar"]: bar2} = {bar: "bar"};
let foo2 = () => "bar";
let {[foo2()]: bar3} = {bar: "bar"};
~~~
!!! error TS2353: Object literal may only specify known properties, and 'bar' does not exist in type '{}'.
let [{[foo]: bar4}] = [{bar: "bar"}];
~~~
!!! error TS2353: Object literal may only specify known properties, and 'bar' does not exist in type '{}'.
let [{[foo2()]: bar5}] = [{bar: "bar"}];
~~~
!!! error TS2353: Object literal may only specify known properties, and 'bar' does not exist in type '{}'.
function f1({["bar"]: x}: { bar: number }) {}
function f2({[foo]: x}: { bar: number }) {}
@@ -47,42 +27,26 @@ tests/cases/compiler/computedPropertiesInDestructuring1.ts(34,26): error TS2353:
let [{[foo()]: bar6}] = [{bar: "bar"}];
~~~~~
!!! error TS2349: Cannot invoke an expression whose type lacks a call signature.
~~~
!!! error TS2353: Object literal may only specify known properties, and 'bar' does not exist in type '{}'.
let [{[foo.toExponential()]: bar7}] = [{bar: "bar"}];
~~~~~~~~~~~~~
!!! error TS2339: Property 'toExponential' does not exist on type 'string'.
~~~
!!! error TS2353: Object literal may only specify known properties, and 'bar' does not exist in type '{}'.
// destructuring assignment
({[foo]: bar} = {bar: "bar"});
~~~
!!! error TS2353: Object literal may only specify known properties, and 'bar' does not exist in type '{}'.
({["bar"]: bar2} = {bar: "bar"});
({[foo2()]: bar3} = {bar: "bar"});
~~~
!!! error TS2353: Object literal may only specify known properties, and 'bar' does not exist in type '{}'.
[{[foo]: bar4}] = [{bar: "bar"}];
~~~
!!! error TS2353: Object literal may only specify known properties, and 'bar' does not exist in type '{}'.
[{[foo2()]: bar5}] = [{bar: "bar"}];
~~~
!!! error TS2353: Object literal may only specify known properties, and 'bar' does not exist in type '{}'.
[{[foo()]: bar4}] = [{bar: "bar"}];
~~~~~
!!! error TS2349: Cannot invoke an expression whose type lacks a call signature.
~~~
!!! error TS2353: Object literal may only specify known properties, and 'bar' does not exist in type '{}'.
[{[(1 + {})]: bar4}] = [{bar: "bar"}];
~~~~~~
!!! error TS2365: Operator '+' cannot be applied to types 'number' and '{}'.
~~~
!!! error TS2353: Object literal may only specify known properties, and 'bar' does not exist in type '{}'.

View File

@@ -1,42 +1,22 @@
tests/cases/compiler/computedPropertiesInDestructuring1_ES6.ts(3,21): error TS2353: Object literal may only specify known properties, and 'bar' does not exist in type '{}'.
tests/cases/compiler/computedPropertiesInDestructuring1_ES6.ts(9,25): error TS2353: Object literal may only specify known properties, and 'bar' does not exist in type '{}'.
tests/cases/compiler/computedPropertiesInDestructuring1_ES6.ts(11,25): error TS2353: Object literal may only specify known properties, and 'bar' does not exist in type '{}'.
tests/cases/compiler/computedPropertiesInDestructuring1_ES6.ts(12,28): error TS2353: Object literal may only specify known properties, and 'bar' does not exist in type '{}'.
tests/cases/compiler/computedPropertiesInDestructuring1_ES6.ts(21,8): error TS2349: Cannot invoke an expression whose type lacks a call signature.
tests/cases/compiler/computedPropertiesInDestructuring1_ES6.ts(21,27): error TS2353: Object literal may only specify known properties, and 'bar' does not exist in type '{}'.
tests/cases/compiler/computedPropertiesInDestructuring1_ES6.ts(22,12): error TS2339: Property 'toExponential' does not exist on type 'string'.
tests/cases/compiler/computedPropertiesInDestructuring1_ES6.ts(22,41): error TS2353: Object literal may only specify known properties, and 'bar' does not exist in type '{}'.
tests/cases/compiler/computedPropertiesInDestructuring1_ES6.ts(25,18): error TS2353: Object literal may only specify known properties, and 'bar' does not exist in type '{}'.
tests/cases/compiler/computedPropertiesInDestructuring1_ES6.ts(29,22): error TS2353: Object literal may only specify known properties, and 'bar' does not exist in type '{}'.
tests/cases/compiler/computedPropertiesInDestructuring1_ES6.ts(31,21): error TS2353: Object literal may only specify known properties, and 'bar' does not exist in type '{}'.
tests/cases/compiler/computedPropertiesInDestructuring1_ES6.ts(32,24): error TS2353: Object literal may only specify known properties, and 'bar' does not exist in type '{}'.
tests/cases/compiler/computedPropertiesInDestructuring1_ES6.ts(34,4): error TS2349: Cannot invoke an expression whose type lacks a call signature.
tests/cases/compiler/computedPropertiesInDestructuring1_ES6.ts(34,23): error TS2353: Object literal may only specify known properties, and 'bar' does not exist in type '{}'.
tests/cases/compiler/computedPropertiesInDestructuring1_ES6.ts(35,5): error TS2365: Operator '+' cannot be applied to types 'number' and '{}'.
tests/cases/compiler/computedPropertiesInDestructuring1_ES6.ts(35,26): error TS2353: Object literal may only specify known properties, and 'bar' does not exist in type '{}'.
==== tests/cases/compiler/computedPropertiesInDestructuring1_ES6.ts (16 errors) ====
==== tests/cases/compiler/computedPropertiesInDestructuring1_ES6.ts (4 errors) ====
// destructuring in variable declarations
let foo = "bar";
let {[foo]: bar} = {bar: "bar"};
~~~
!!! error TS2353: Object literal may only specify known properties, and 'bar' does not exist in type '{}'.
let {["bar"]: bar2} = {bar: "bar"};
let {[11]: bar2_1} = {11: "bar"};
let foo2 = () => "bar";
let {[foo2()]: bar3} = {bar: "bar"};
~~~
!!! error TS2353: Object literal may only specify known properties, and 'bar' does not exist in type '{}'.
let [{[foo]: bar4}] = [{bar: "bar"}];
~~~
!!! error TS2353: Object literal may only specify known properties, and 'bar' does not exist in type '{}'.
let [{[foo2()]: bar5}] = [{bar: "bar"}];
~~~
!!! error TS2353: Object literal may only specify known properties, and 'bar' does not exist in type '{}'.
function f1({["bar"]: x}: { bar: number }) {}
function f2({[foo]: x}: { bar: number }) {}
@@ -48,40 +28,24 @@ tests/cases/compiler/computedPropertiesInDestructuring1_ES6.ts(35,26): error TS2
let [{[foo()]: bar6}] = [{bar: "bar"}];
~~~~~
!!! error TS2349: Cannot invoke an expression whose type lacks a call signature.
~~~
!!! error TS2353: Object literal may only specify known properties, and 'bar' does not exist in type '{}'.
let [{[foo.toExponential()]: bar7}] = [{bar: "bar"}];
~~~~~~~~~~~~~
!!! error TS2339: Property 'toExponential' does not exist on type 'string'.
~~~
!!! error TS2353: Object literal may only specify known properties, and 'bar' does not exist in type '{}'.
// destructuring assignment
({[foo]: bar} = {bar: "bar"});
~~~
!!! error TS2353: Object literal may only specify known properties, and 'bar' does not exist in type '{}'.
({["bar"]: bar2} = {bar: "bar"});
({[foo2()]: bar3} = {bar: "bar"});
~~~
!!! error TS2353: Object literal may only specify known properties, and 'bar' does not exist in type '{}'.
[{[foo]: bar4}] = [{bar: "bar"}];
~~~
!!! error TS2353: Object literal may only specify known properties, and 'bar' does not exist in type '{}'.
[{[foo2()]: bar5}] = [{bar: "bar"}];
~~~
!!! error TS2353: Object literal may only specify known properties, and 'bar' does not exist in type '{}'.
[{[foo()]: bar4}] = [{bar: "bar"}];
~~~~~
!!! error TS2349: Cannot invoke an expression whose type lacks a call signature.
~~~
!!! error TS2353: Object literal may only specify known properties, and 'bar' does not exist in type '{}'.
[{[(1 + {})]: bar4}] = [{bar: "bar"}];
~~~~~~
!!! error TS2365: Operator '+' cannot be applied to types 'number' and '{}'.
~~~
!!! error TS2353: Object literal may only specify known properties, and 'bar' does not exist in type '{}'.