From 232a668ce082e5a6ec570b7009c6444e464d6749 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Burzy=C5=84ski?= Date: Sun, 17 Jul 2022 08:55:02 +0200 Subject: [PATCH] Improve ancestor lookup when checking if an expression is spread into an object --- src/compiler/checker.ts | 3 +-- ...ningObjectExpressionContextualType.symbols | 23 ++++++++++++++++++ ...iningObjectExpressionContextualType.types} | 24 ++++++++++++++++++- ...nWithinIIFEReturnAssignedtoPattern.symbols | 11 --------- ...ontainingObjectExpressionContextualType.ts | 15 ++++++++++++ ...essionWithinIIFEReturnAssignedtoPattern.ts | 8 ------- 6 files changed, 62 insertions(+), 22 deletions(-) create mode 100644 tests/baselines/reference/spreadExpressionContainingObjectExpressionContextualType.symbols rename tests/baselines/reference/{spreadExpressionWithinIIFEReturnAssignedtoPattern.types => spreadExpressionContainingObjectExpressionContextualType.types} (51%) delete mode 100644 tests/baselines/reference/spreadExpressionWithinIIFEReturnAssignedtoPattern.symbols create mode 100644 tests/cases/compiler/spreadExpressionContainingObjectExpressionContextualType.ts delete mode 100644 tests/cases/compiler/spreadExpressionWithinIIFEReturnAssignedtoPattern.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 8492d21ba0e..559ff42fc89 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -28086,8 +28086,7 @@ namespace ts { // type with those properties for which the binding pattern specifies a default value. // If the object literal is spread into another object literal, skip this step and let the top-level object // literal handle it instead. - const spreadOrOutsidePossibleObjectParent = findAncestor(node, n => n.kind === SyntaxKind.SpreadAssignment || isStatement(n) || isArrowFunction(n))!; - if (contextualTypeHasPattern && spreadOrOutsidePossibleObjectParent.kind !== SyntaxKind.SpreadAssignment) { + if (contextualTypeHasPattern && findAncestor(node, n => n === contextualType.pattern!.parent || (n.kind === SyntaxKind.SpreadAssignment && getContextualType(n.parent as Expression, /*contextFlags*/undefined)!.pattern === contextualType.pattern))!.kind !== SyntaxKind.SpreadAssignment) { for (const prop of getPropertiesOfType(contextualType)) { if (!propertiesTable.get(prop.escapedName) && !getPropertyOfType(spread, prop.escapedName)) { if (!(prop.flags & SymbolFlags.Optional)) { diff --git a/tests/baselines/reference/spreadExpressionContainingObjectExpressionContextualType.symbols b/tests/baselines/reference/spreadExpressionContainingObjectExpressionContextualType.symbols new file mode 100644 index 00000000000..2b95e9c2fff --- /dev/null +++ b/tests/baselines/reference/spreadExpressionContainingObjectExpressionContextualType.symbols @@ -0,0 +1,23 @@ +=== tests/cases/compiler/spreadExpressionContainingObjectExpressionContextualType.ts === +// repro #49585 + +const { value } = (() => ({ +>value : Symbol(value, Decl(spreadExpressionContainingObjectExpressionContextualType.ts, 2, 7)) + + value: "", +>value : Symbol(value, Decl(spreadExpressionContainingObjectExpressionContextualType.ts, 2, 27)) + + ...(true ? {} : {}), +}))(); + +// repro 49684#discussion_r920545763 + +const { value2 } = { +>value2 : Symbol(value2, Decl(spreadExpressionContainingObjectExpressionContextualType.ts, 9, 7)) + + value2: "", +>value2 : Symbol(value2, Decl(spreadExpressionContainingObjectExpressionContextualType.ts, 9, 20)) + + ...(() => true ? {} : {})(), +}; + diff --git a/tests/baselines/reference/spreadExpressionWithinIIFEReturnAssignedtoPattern.types b/tests/baselines/reference/spreadExpressionContainingObjectExpressionContextualType.types similarity index 51% rename from tests/baselines/reference/spreadExpressionWithinIIFEReturnAssignedtoPattern.types rename to tests/baselines/reference/spreadExpressionContainingObjectExpressionContextualType.types index dc56d0def76..2e3765e2f69 100644 --- a/tests/baselines/reference/spreadExpressionWithinIIFEReturnAssignedtoPattern.types +++ b/tests/baselines/reference/spreadExpressionContainingObjectExpressionContextualType.types @@ -1,4 +1,4 @@ -=== tests/cases/compiler/spreadExpressionWithinIIFEReturnAssignedtoPattern.ts === +=== tests/cases/compiler/spreadExpressionContainingObjectExpressionContextualType.ts === // repro #49585 const { value } = (() => ({ @@ -21,3 +21,25 @@ const { value } = (() => ({ >{} : {} }))(); + +// repro 49684#discussion_r920545763 + +const { value2 } = { +>value2 : string +>{ value2: "", ...(() => true ? {} : {})(),} : { value2: string; } + + value2: "", +>value2 : string +>"" : "" + + ...(() => true ? {} : {})(), +>(() => true ? {} : {})() : {} +>(() => true ? {} : {}) : () => {} +>() => true ? {} : {} : () => {} +>true ? {} : {} : {} +>true : true +>{} : {} +>{} : {} + +}; + diff --git a/tests/baselines/reference/spreadExpressionWithinIIFEReturnAssignedtoPattern.symbols b/tests/baselines/reference/spreadExpressionWithinIIFEReturnAssignedtoPattern.symbols deleted file mode 100644 index 92531907d8a..00000000000 --- a/tests/baselines/reference/spreadExpressionWithinIIFEReturnAssignedtoPattern.symbols +++ /dev/null @@ -1,11 +0,0 @@ -=== tests/cases/compiler/spreadExpressionWithinIIFEReturnAssignedtoPattern.ts === -// repro #49585 - -const { value } = (() => ({ ->value : Symbol(value, Decl(spreadExpressionWithinIIFEReturnAssignedtoPattern.ts, 2, 7)) - - value: "", ->value : Symbol(value, Decl(spreadExpressionWithinIIFEReturnAssignedtoPattern.ts, 2, 27)) - - ...(true ? {} : {}), -}))(); diff --git a/tests/cases/compiler/spreadExpressionContainingObjectExpressionContextualType.ts b/tests/cases/compiler/spreadExpressionContainingObjectExpressionContextualType.ts new file mode 100644 index 00000000000..56c334414d1 --- /dev/null +++ b/tests/cases/compiler/spreadExpressionContainingObjectExpressionContextualType.ts @@ -0,0 +1,15 @@ +// @noEmit: true + +// repro #49585 + +const { value } = (() => ({ + value: "", + ...(true ? {} : {}), +}))(); + +// repro 49684#discussion_r920545763 + +const { value2 } = { + value2: "", + ...(() => true ? {} : {})(), +}; diff --git a/tests/cases/compiler/spreadExpressionWithinIIFEReturnAssignedtoPattern.ts b/tests/cases/compiler/spreadExpressionWithinIIFEReturnAssignedtoPattern.ts deleted file mode 100644 index 4652c802051..00000000000 --- a/tests/cases/compiler/spreadExpressionWithinIIFEReturnAssignedtoPattern.ts +++ /dev/null @@ -1,8 +0,0 @@ -// @noEmit: true - -// repro #49585 - -const { value } = (() => ({ - value: "", - ...(true ? {} : {}), -}))(); \ No newline at end of file