GeezerVisonThe World Wide Web, restored to 800 pixels of glory. | ||||||||||||||||||||
| Home|About|Gaming cabinet|Archives|How it works|Starter sites | ||||||||||||||||||||
GeezerVison is showing github.com — Allow non-unit types in union discriminants by ahejlsberg · Pull Request #27695 · microsoft/TypeScript Conversation
Member
With this PR we permit non-unit types in union type discriminants. Specifically, we now consider a property of a union type to be a discriminant property if it has a union type containing at least one unit type and no instantiable types. For example: type Result<T> = { error?: undefined, value: T } | { error: Error }; function test(x: Result<number>) { if (!x.error) { x.value; // number } else { x.error.message; // string } } test({ value: 10 }); test({ error: new Error("boom") }); Inspired by #27631 which was closed in favor of this PR. Fixes #24193.
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page. All reactions
Collaborator
All reactions
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page.
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could it be worth adding a test that includes constrained generics? My reasoning being that in the future it might be worth considering discriminants that have constrained parameters because they are comparable to literals in some form. Having a test that would flag any changes might be helpful. Something like: function f21<T extends number>(x: { a: undefined; b: { x: number } } | { a: T, b: { y: number } }) { if (x.a === undefined) { x.b = { y: 42 }; } }
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page. All reactions
Member
All reactions
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page.
|
There was an error while loading. Please reload this page.
|
Wesley Wigham (@weswigham)
|
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
Jack Williams (@jack-williams) You're actually right about type I think it is fine to document that discriminants must be truly disjoint types, and that |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
Anders Hejlsberg (@ahejlsberg) Thanks for the explanation. I managed to confuse myself when I experimented with turning off union reduction and finding that it did not have an effect in this example.
Yes, I agree with your assessment here. The asymmetry brought about by trying to narrow types like |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
Fair enough. I just wanted to point out that we still don't narrow all the things we look like we could because of how the broader string type and the specific literal type are related. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
In any case, this definitely looks like an improvement, and we can always adjust it to recognize more types as discriminable in the future if need be.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
Any chance this will allow using tuples as discriminants? e.g. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
Brian Ingles (@bmingles) I believe your example will narrow correctly since v3.1. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
Successfully merging this pull request may close these issues.
Allow to use null as discriminator for tagged union
There was an error while loading. Please reload this page.