-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
Intersection type operator doesn't discriminate Union Types #13203
Comments
type if i understand correctly, what you want is: type A = {tag: 'a', a: 1} | B;
type B = {tag: 'b', b: 1};
declare var b : B
let z = b.b |
The type The TS specs says:
To clarify, in this code: type A = {tag: 'a', a: 1}
type B = {tag: 'b', b: 1}
type TaggedAsB = {tag: 'b'} The I think this is not a TS bug, but it can be seen as a current shortcoming and as a nice feature to have. Maybe TS should collapse the 1- (B | A) & TaggedAsB
2- ({tag : 'b', b : 1} | {tag: 'a' , a: 1}) & {tag: 'b'}
3- {tag : 'b', b : 1} | {tag: 'a' & 'b', a: 1}
4- {tag : 'b', b : 1} | never
5- {tag : 'b', b : 1} // Discriminated Union case Note, the sample you give is not what I want (and note, you didn't use |
Having a type with no values is fine. it is not an error to have a type that does not have any values. e.g. if the intention here is to cast, i would cast to |
I should add, it is intentional that it is not an error, and it is intentional that intersection of primitives and/or literals do not reduce to |
Then the feature request can be restated as this: Make TS discriminate/narrow an union when one or more of his constituent types have no possible values, but without reducing them to the To show you why I don't want to use castings, here is my use case: type Event = ({eventName : "EVENT_A", dataA : any} |
{eventName : "EVENT_B", dataB : any})
// define a callback for an specific event, use an intersection type operator to select
// a case from the Event DU.
function handlerEventA(event : Event & {eventName: "EVENT_A"}) {
// with this new feature, here we don't need a typeguard, TS knows
// what specific DU case is event:
let x = event.dataA
} I want to avoid the need of defining a type for each event name. By having the possibility of choosing a case in a discriminating union using an intersection type, this can be easily resolved and the |
I am not sure i see the reason behind writing an intersection type in these locations. writing function handlerEventA(event : {eventName : "EVENT_A", dataA : any}) { seems to be as much work as |
If you do that, then you must replicate the entire specific event type definition in each possible handler, which can be huge, or assign a type name for each one of them (what I want to avoid). I think this can be useful in many other cases. To be more specific, the feature request is: Given a Discriminated Union type, make possible to create a new type that narrows to an specific case of the DU (creating it at the static type level, without using runtime typeguards). |
PD: Maybe it will be better to change the title of this issue to "make possible to narrow Discriminated Unions statically" and add the feature request label. |
please close this issue, I re-stated it in a more clear form at #13300 |
Expected behavior:
b
(typeB
) only possible value fortag
property is'b'
, so it must be discriminated to{tag : 'b' , 'b' : 1}
without needing to enclose it in aif(b.tag == 'b')
type guardActual behavior:
b
(typeB
) is not discriminated, needs type guards just like plainA
TypeScript Version: 2.0.6
The text was updated successfully, but these errors were encountered: