-
Notifications
You must be signed in to change notification settings - Fork 12.8k
Narrow subtype-reduction-prone unions to their narrowest constituent #47731
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
Comments
This is expected; arrays are assignable to |
@fatcerberus while it might be the case, I don't see how that makes it any less unexpected? Or am I wrong to expect that since I explicitly pass an array the typings should narrow to that? I tried |
In general, having overlapping types in a union is going to give you a bad time. |
You could write declare let a: { push?: never } | any[] | undefined
if (a === undefined) {
a = [] // I expect this line to have TS understand that a is any[] from now on
} else if (!Array.isArray(a)) {
throw new Error()
} Subtype-reducing unions aren't great but it seems like we could fix the narrowing-on-assignment logic to do a subtype reduction on any resulting union, since that's assured to be sound. |
@fatcerberus I very much understand this, hence why we can do the following: const b: any[] = []
const c: object = b What I think isn't ergonomic is not narrowing the type to what's being assigned explicitly: let d: object | any[] | undefined
d = []
takeArray(d) // should work, currently doesn't But @RyanCavanaugh's suggestion works! let d: { push?: never } | any[] | undefined
d = []
takeArray(d) // works @fatcerberus thank you for explaining how TypeScript currently sees this scenario but no matter what it does, the point of my issue is that maybe there would be something to change so that it is more ergonomical. |
Indeed, and I agree this is less than ergonomic. Note @RyanCavanaugh's renaming of the issue which is one way this could be solved. It's just that you posted this as a bug report while the observed behavior actually falls out naturally from the rules of the type system, so it seemed like a misunderstanding that I was trying to clear up (because fixing this adds yet another ad-hoc rule to type inference/narrowing that's not based purely on assignability, and IMO type inference in TS is way too ad-hoc as it is). Apparently Ryan agrees with you that it's a bug though so... yeah 😛 |
Bug Report
Type narrowing doesn't seem to take into account an assignment I made to ensure the variable has the right type.
Maybe related? #43584 (comment)
🔎 Search Terms
type narrowing assignment
🕗 Version & Regression Information
4.5.4
⏯ Playground Link
Playground Link
💻 Code
🙁 Actual behavior
a
has typeobject | any[]
🙂 Expected behavior
a
to have typeany[]
The text was updated successfully, but these errors were encountered: