Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
wusiquan opened this issue Sep 7, 2023 · 4 comments
Labels
Experimentation Needed Someone needs to try this out to see what happens Suggestion An idea for TypeScript
Milestone

Comments

@wusiquan
Copy link

wusiquan commented Sep 7, 2023

πŸ”Ž 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

@jcalz
Copy link
Contributor

jcalz commented Sep 7, 2023

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)

@wusiquan wusiquan changed the title discriminated union type narrow when desturcting object within desturct array discriminated union type narrow when destructuring object within desturct array Sep 7, 2023
@wusiquan
Copy link
Author

wusiquan commented Sep 7, 2023

@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.

@andrewbranch andrewbranch added Suggestion An idea for TypeScript Experimentation Needed Someone needs to try this out to see what happens labels Sep 11, 2023
@andrewbranch andrewbranch added this to the Backlog milestone Sep 11, 2023
@kykungz
Copy link

kykungz commented Oct 17, 2023

Related use case: TanStack/query#6162

@mattfbacon
Copy link

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
Labels
Experimentation Needed Someone needs to try this out to see what happens Suggestion An idea for TypeScript
Projects
None yet
Development

No branches or pull requests

5 participants