Skip to content

discriminated union type narrow when destructuring object within desturct arrayΒ #55664

Open

Description

πŸ”Ž Search Terms

destructuring object within destructured array, discriminated union

πŸ•— Version & Regression Information

the error part appeared in every version I tried

⏯ Playground Link

https://www.typescriptlang.org/play?target=1&ts=5.2.2#code/C4TwDgpgBAYglgJwM7AJLAgWygXigbwCgopRIAuKAcgDNEUrioA3AQwBsBXCSlBOAHYBzQgF9ChMtADKEAMYB7AQBN0WXASZTKVJPKXLGJNlx5QBnTACMICMRKlQAKgAtEqjNjxES26sDcEQyYTbkorBQV2CFYBe0JFARQoVkoACnhkNE8oAB8oWUSPdXzXdzVMAEoAbQBdDTqJAHom0ghkgEZCVgA6GgUEAFFWORc0tPxScAgAGhYObihRStwAPk0SOBooNMccfeo6LKoVnxIoFqgFAGteYH5hJhJEpCiIHvYFITTQiEqmcTLZqtDDJABMhH6CB2L2ABCmkDmvyWV22rFOTC2Oz2B1o9GAJw250uNzuDxE5ygLzeHy+PwWfwB8QSSmSVko1Vg+IqeQK+hUPNKgWK2FqdQatWBbWSAGZIQMYay4ZzmFB6gptlYMZttj8eji8Hjjtria0bk8qayaZ9vswer9-iRAVLQXCACyEKx9AbDUbjaqTKRIhlLWorHDrM5Y3bTXC4o4ME0kS4CBRw0lQPiCIS8izWWy8iJvWIW6nRWm2hmOpZif6ES6uqAAVnl0LSsKgnMD02DphR6s1JujBsO+MJZ2TrVT6dumfu2dzlhs0PyReiJcpZfeNvppmrgKAA

πŸ’» Code

type FirstItem = {
  type: 'first'
  value: string
}

type SecondItem = {
  type: 'second'
  value: number
}

type ThirdItem = {
  type: 'third'
  value: boolean
}

const a: (FirstItem | SecondItem | ThirdItem)[] = []

// test 1
a.forEach(({ type, value }) => {
  if (type === 'first') {
    // ok: string
    console.log(value)
  }
})

// test 2
for (const { type, value } of a) {
  if (type === 'first') {
    // ok: string
    console.log(value)
  }
}


const b: [ FirstItem | SecondItem | ThirdItem ][] = []

// test 3
for (const [ v ] of b) {
  if (v.type === 'first') {
    // ok
    console.log(v.value)
  }
}

// test 4
b.forEach(([{ type, value }]) => {
  if (type === 'first') {
    // not ok: string | number | boolean
    console.log(value)
  }
})

// test 5
for (const [ { type, value } ] of b) {
  if (type === 'first') {
    // not ok: string | number | boolean
    console.log(value)
  }
}

πŸ™ Actual behavior

the code above, test4 and test5 can not narrow to the string type like test1, test2 or test3

πŸ™‚ Expected behavior

I expected the value in the loop to infer successfully

Additional information about the issue

No response

Activity

  1. jcalz commented on Sep 7, 2023

    @jcalz
    Contributor

    Please edit the title to use the term "destructuring" instead of "desturcting" so that title searches can find it.


    Looks like a missing feature as opposed to a bug, since #46266 only operates if the thing being destructured is a discriminated union, and [ FirstItem | SecondItem | ThirdItem ][] is not a discriminated union.

    #46266 (comment)

  2. changed the title [-]discriminated union type narrow when desturcting object within desturct array[/-] [+]discriminated union type narrow when destructuring object within desturct array[/+] on Sep 7, 2023
  3. wusiquan commented on Sep 7, 2023

    @wusiquan
    Author

    Joe Calzaretta (@jcalz) thank you. I agree this is more than a missing feature, after reading the linked issue. Type [ FirstItem | SecondItem | ThirdItem ], the first item of the array type, is a discriminated union, but it is nested. Destructuring the nested object(array) all at once or in a seperate way, when using forEach and for...of, the results are not the same. It seems a little complex.

  4. kykungz commented on Oct 17, 2023

    @kykungz

    Related use case: TanStack/query#6162

  5. mattfbacon commented on Apr 9, 2024

    @mattfbacon

    Is this the same issue?

    // gen: Generator<number>
    let value;
    while (!({ value } = gen.next()).done) {
      // `value` is not properly inferred as number here.
    }
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

    Experimentation NeededSomeone needs to try this out to see what happensSuggestionAn idea for TypeScript

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions