You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
aliasing discriminated union tag breaks case analysis #10830
typeA={t: "a",a: string};typeB={t: "b",b: string};typeU=A|B;consta: U={t: "a",a: "a"}asU;if(a.t==="b"){a.b;// works as expected}const{t}=a;if(t==="b"){a.b;// error TS2339: Property 'b' does not exist on type 'U'.}
Expected behavior:
The type of a.t should correctly transfer to t when assigning or using destructuring. t should be usable as discriminant.
Actual behavior:
The type of t is widened from "a" | "b" to string and therefore can not be used as discriminant any more.
As the same happens also for flow (See facebook/flow#2409), it may be my thinking that is a little bit off. But I think that the case should be valid. The programmer should not be forced to repeat base. all over, that’s what variables are for.
The type of a.t should correctly transfer to t when assigning or using destructuring. t should be usable as discriminant.
Tracking this correctly would require that variables "remember where they came from" and what implications that has on other variables. It'd probably be possible/reasonable to make that work at 1 level of indirection (rather than at 0 levels of indirection), but tracking it for N levels of indirection would be very complex, and then presumably you'd be surprised when it worked at 1 level of indirection but not 2.
So given the choice between "be surprised at 2 and things get way more complex in the compiler implementation" vs "be surprised at 1", we're generally sticking with the latter.
declareconstaction: {type: "A",payload: number}|{type: "B",payload: string};const{ type, payload }=action;switch(type){case'SOME_STRING': // "SOME_STRING"" is not compatible with "A" | "B"}
Activity
RyanCavanaugh commentedon Sep 9, 2016
Tracking this correctly would require that variables "remember where they came from" and what implications that has on other variables. It'd probably be possible/reasonable to make that work at 1 level of indirection (rather than at 0 levels of indirection), but tracking it for N levels of indirection would be very complex, and then presumably you'd be surprised when it worked at 1 level of indirection but not 2.
So given the choice between "be surprised at 2 and things get way more complex in the compiler implementation" vs "be surprised at 1", we're generally sticking with the latter.
ligaz commentedon Sep 15, 2016
What about the following case:
Is it too complex or there is possibility that you can add support for it?
mhegazy commentedon Sep 15, 2016
Stefan Dobrev (@ligaz) this already works as intended:
ligaz commentedon Sep 16, 2016
The problem is that the payload is not typed if the tag is matched:
mhegazy commentedon Sep 16, 2016
There is no way to know that there is a relationship between the two variables.