-
Notifications
You must be signed in to change notification settings - Fork 12.8k
Type guard not work in union type of objects #30506
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Comments
The type of Narrowing the parent object is only done in specific scenarios, when the property is considered a discriminant for the union. A property is considered as a discriminant property if:
Might be other scenarios that I haven't quoted here, but the scenario in the code is not covered by any as far as I can tell. As a side note, you can discriminated the union in the example using an function fn(i: { foo: string, bar: number, baz: boolean } | { foo: number, bar: boolean }) {
if ('baz' in i) {
i.foo // string
i.bar // number
}
} Or use a custom type guard. |
@dragomirtitian I have a question on why TS doesn't provide us the typeof guarding on codes above? Is there an underlying unsafe situation? |
@zheeeng These cases must be specifically crafted to work, they don't just happen. I am not sure there is a definitive answer as to why more cases are not considered as property discriminants but @ahejlsberg mentions in the original discriminated union PR in a response to a similar request to yours that:
Maybe someone in the team can tell us if this is still the definitive reason or there are other concerns. |
The lack of narrowing isn't because the type of |
As a newbie, this can be confusing. For example, when I look at this stackoverflow question, the code looks like it should compile (to me). The official documentation has a section for nearly every form of JavaScript "narrowing" I can think of. Then it goes even further, providing TypeScript-only solutions like Type Predicates. From my perspective, the most compelling reason to implement this is to make the language feel consistent. Currently, Now having said all that, I just wanted to answer your question since nobody else did. In my opinion, this might be more of a documentation issue than a problem with the language. And for that reason, I plan to open a separate issue. |
TypeScript Version: 3.3.3.3333
Search Terms:
type guard, union type of objects, typeof
Code
Code 2
Expected behavior:
in 'if' branch, ‘i’ should be { foo: string, bar: number, baz: boolean }
Actual behavior:
As comments says.
Playground Link:
http://www.typescriptlang.org/play/index.html#src=function%20fn(i%3A%20%7B%20foo%3A%20string%2C%20bar%3A%20number%2C%20baz%3A%20boolean%20%7D%20%7C%20%7B%20foo%3A%20number%2C%20bar%3A%20boolean%20%7D)%20%7B%0D%0A%20%20%20%20if%20(typeof%20i.foo%20%3D%3D%3D%20'string')%20%7B%0D%0A%20%20%20%20%20%20%20%20i.foo%20%2F%2F%20string%20%7C%20number%0D%0A%20%20%20%20%20%20%20%20i.bar%20%2F%2F%20number%20%7C%20boolean%0D%0A%20%20%20%20%7D%0D%0A%7D%0D%0A
The text was updated successfully, but these errors were encountered: