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
Intersected function type returns only first constituent's return type #10508
interfaceA{a: boolean;}interfaceB{b: boolean;}declareconstfooAB: (()=>A)&(()=>B);constab=fooAB();// A
Expected behavior:ab has type A & B
Actual behavior:ab has type A
Perhaps this is being treated as an overloaded call signature, and () => A just happens to be first. If this is by design, it would be great to learn about any known workarounds.
Mohamed Hegazy (@mhegazy) I understand that the current behavior is practical, but the only way a function could actually implement the intersection would be by returning a value of A & B. Maybe it is not realistic but since, IIRC the compiler will always pick the first overload, it would be reasonable to expect the intersection.
The compiler has no way of merging signatures in the general case. this one seems simple enough, but what happens if there are parameters involved, what if they have different count, what if one of them is generic, what if the parameter types do not agree.. for instance (a: number, b:string) => A and (a: string, b: number) => B is this (a: number|string, b: number|string) => A&B ? i do not think this is correct.
Mohamed Hegazy (@mhegazy) I agree that's not correct specifically because the functions have different parameter types. This means that using the union of each corresponding parameter is not accurate. Interestingly though, this also means that there is a way to select the overload that you want, so I don't think these signatures need to be merged.
Obviously it's not a trivial problem.
I think the intuitive behavior would be to only merge signatures when they match exactly in arity and parameter types.
My reasoning is that there's no way to statically select and thus differentiate between the different signatures that are available without using a type assertion.
Activity
kitsonk commentedon Aug 24, 2016
this is covariance, right? dupe of #1394?
mhegazy commentedon Aug 24, 2016
(() => A) & (() => B);is not equivalant to(() => A & B);.(() => A) & (() => B);is equivalent toaluanhaddad commentedon Sep 4, 2016
Mohamed Hegazy (@mhegazy) I understand that the current behavior is practical, but the only way a function could actually implement the intersection would be by returning a value of
A & B. Maybe it is not realistic but since, IIRC the compiler will always pick the first overload, it would be reasonable to expect the intersection.mhegazy commentedon Sep 7, 2016
The compiler has no way of merging signatures in the general case. this one seems simple enough, but what happens if there are parameters involved, what if they have different count, what if one of them is generic, what if the parameter types do not agree.. for instance
(a: number, b:string) => Aand(a: string, b: number) => Bis this(a: number|string, b: number|string) => A&B? i do not think this is correct.aluanhaddad commentedon Sep 7, 2016
Mohamed Hegazy (@mhegazy) I agree that's not correct specifically because the functions have different parameter types. This means that using the union of each corresponding parameter is not accurate. Interestingly though, this also means that there is a way to select the overload that you want, so I don't think these signatures need to be merged.
Obviously it's not a trivial problem.
I think the intuitive behavior would be to only merge signatures when they match exactly in arity and parameter types.
My reasoning is that there's no way to statically select and thus differentiate between the different signatures that are available without using a type assertion.