-
Notifications
You must be signed in to change notification settings - Fork 12.5k
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
TypeScript doesn't correctly narrow union types #54270
Comments
Hmm it looks like I can get the above code to work with the following change: interface Book {
type: undefined
author: string
}
interface Collection {
type: 'collection'
title: string
} So, even though |
Broadly speaking, control flow analysis considers there to be two kinds of conditions: those that affect the type of a variable, and those that don't. In this case, the If it's not always true, then we have to entertain the possibility that indeed some values that have a |
In other words, TypeScript is expecting you to uniformly either acknowledge or reject the possible existence of the interface BookCollection extends Book {
type: 'collection';
}
interface Collection {
type: 'collection';
title: string;
} |
I don't really understand at all, but that's okay; I'd probably need some kind of YouTube course to understand how TypeScript understands types. Somewhat related: The following would probably be better written as a feature request (if it hasn't already), but I feel like there are a bunch of times where I want to just assert to TypeScript that something is of a certain type within a scope, without having to use parentheses with each reference, like: if (condition) {
assert item is Book;
console.log(item.prop1, item.prop2)
} else {
assert item is Collection;
console.log(item.prop3, item.prop4)
} I know you can do type-narrowing assertions with functions or variable assignment, it would just be nice to have something that's erasable at runtime. I used to run into this all the time when working with the |
Ah looks like the second part is a (partial) duplicate of #53201 |
This issue has been marked 'Working as Intended' and has seen no recent activity. It has been automatically closed for house-keeping purposes. |
Bug Report
Given these interfaces:
TypeScript correctly infers the type from an if statement, but doesn't, by process of elimination, infer the other type in the union.
This is an illogical error. If there are only 2 possible types, then if the first type is correctly inferred, then the else statement must be the other type, as the other interface does not have a
type
key nor a type key with a value ofcollection
.🔎 Search Terms
So, I searched, and this could be a duplicate of #52272 which was marked a duplicate of #43026, but it's not clear its a duplicate, as those describe an a / b / c case where this is an a / b case.
Is the problem that the other object does not have a
type
key? Is there a scenario where it could be narrowed?🕗 Version & Regression Information
⏯ Playground Link
Playground link with relevant code
💻 Code
Shown above
🙁 Actual behavior
Types were not narrowed
🙂 Expected behavior
Union types are narrowed
The text was updated successfully, but these errors were encountered: