Skip to content

Nested destructuring does not narrow dependent parametersΒ #48378

Closed

Description

Bug Report

πŸ”Ž Search Terms

destructuring destructured dependent parameters nested control flow analysis

πŸ•— Version & Regression Information

  • This changed between versions 4.5.5 and 4.6

⏯ Playground Link

Playground link with relevant code

πŸ’» Code

declare const Tuple: [true, string] | [false, number];
const [[val1, val2]] = [Tuple];
if (val1) {
	val2 // string | number
}

πŸ™ Actual behavior

TypeScript does not correctly narrow val2 when narrowing val1 if it's in any type of nested destructuring.

πŸ™‚ Expected behavior

I expect it to behave the same as directly destructuring the object.

Activity

  1. jtbandes commented on Jun 21, 2022

    @jtbandes
    Contributor

    Is this the same issue?

    type T = { path: ['one'], value: string } | { path: ['two'], value: number }
    
    function foo(payload: T) {
      if (payload.path[0] === 'one') {
        payload.value  // string | number, should be just string
      }
    }
  2. Fireboltofdeath commented on Jun 22, 2022

    @Fireboltofdeath
    Author

    This issue is referring to the control flow analysis of destructured unions so I don't believe this is related to that issue.

  3. RyanCavanaugh commented on Sep 8, 2026

    @RyanCavanaugh
    Member

    This is fixed by #56306. The nested tuple binding in the original example now preserves the dependency between the discriminant and its paired value: value2 is narrowed to string after if (value1).

    The example still reports TS2322 in 5.4.0-dev.20231128 and is clean in 5.4.0-dev.20231129, TypeScript 6.0.3, and the current native compiler.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    BugA bug in TypeScriptDomain: check: Control FlowThe issue relates to control flow analysisFixedA PR has been merged for this issueHelp WantedYou can do this

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions