-
Notifications
You must be signed in to change notification settings - Fork 12.8k
Type exhaustiveness not working with in
operator guard
#48256
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
let obj!: { foo: string } | { foo: number };
if ("foo" in obj) {
obj.foo;
} else {
assertNever(obj); // now it works
} |
@fatcerberus I see. However, this is a regression and may indicate that something is broken more deeply in TypeScript. The fact that it works with two branches that are both matched by the guard re-inforces the idea that this is some kind of "edge condition" bug. |
In principle this is true, however in practice treating all types as unions now would be a massive breaking change, since the distinction matters in other places too (distributive behavior of conditional types, e.g.). It is not a goal of TypeScript's design to be mathematically sound.
As mentioned, the distinction that matters here is whether the type being guarded is a union type or not, and is by design. See #38963. |
This was an intentional change; see #38608 (comment) |
Thanks @RyanCavanaugh. |
Bug Report
π Search Terms
in narrow narrowing guard
π Version & Regression Information
β― Playground Link
Playground link with relevant code
π» Code
π Actual behavior
The call to
assertNever
is marked error becauseobj
is still typed{ foo: string }
.Interestingly it does work if the type of
obj
has more than one branch. The problem seems present only when there is a single branch in the union type.Also, it does work when using a type guard function.
π Expected behavior
obj
should have typenever
in theelse
branch, as the presence offoo
property has been ruled out by the guard.The text was updated successfully, but these errors were encountered: