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
function ...args with generic union narrows incorrectly after second param #31413
//setuptypeQueryField<T>=keyofT;interfaceFunctionField<T>{fn: 'count'|'avg';alias?: string;field: QueryField<T>;}classfieldBuilder<T>{publicselect<FextendsFunctionField<T>,PextendsQueryField<T>>(...args: Array<P|F>){}}//example errorinterfaceFoo{x: string;y: number;z: boolean;}letbuilder=newfieldBuilder<Foo>();//worksbuilder.select('x','y','z');//Type Error: Argument of type '"y"' is not assignable to parameter of type '"x" | FunctionField<Foo>'.builder.select({fn: 'count',field: 'x'},'x','y');
Expected behavior:
I would expect that my ...args array could be any number of items from FunctionField<T> or QueryField<T>...
Actual behavior:
As soon as I mix the types, it starts to narrow the QueryField<T> based on the first type passed it.
In general, type parameters should always be kept to a minimum. It is suspicious to have type parameters that don't occur both in an input position (i.e. parameter) and an output position (i.e. return type or callback parameter). And it is particularly suspicious to have type parameters that only occur once in a signature (since you might as well replace them with their constraint).
Anders Hejlsberg (@ahejlsberg) I came to that realization after submitting this (which is part of the reason I said the MRE doesn't really make sense). Just typing the parameters directly does fix the issue.
I didn't close it because it still seemed like a bug? If not, feel free to close this out
So, the reason it worked in earlier versions is because we failed to make any inferences for P and F and just reverted to the constraints. With #29847 we now do make inferences for P and F. But because there is nothing discerning about P vs. F (other than constraints which aren't considered until after inference is finished) the inferences end up being poor. So, we now fail in a slightly different manner that causes an error. But, as I alluded to above, the type parameters should just be eliminated.
Activity
ChuckJonas commentedon May 15, 2019
Also worth note, I only started seeing this issue once I upgraded from 3.3.1 -> 3.4.x
ChuckJonas commentedon May 15, 2019
also, I know the MRE doesn't make sense, but it's the simplest way I could reproduce the error
ahejlsberg commentedon May 15, 2019
Before I address the issue, let me ask a question. Are
FandPused anywhere else (such as in the return type) in the signature?If not, why not write the signature like this:
In general, type parameters should always be kept to a minimum. It is suspicious to have type parameters that don't occur both in an input position (i.e. parameter) and an output position (i.e. return type or callback parameter). And it is particularly suspicious to have type parameters that only occur once in a signature (since you might as well replace them with their constraint).
ChuckJonas commentedon May 15, 2019
Anders Hejlsberg (@ahejlsberg) I came to that realization after submitting this (which is part of the reason I said the MRE doesn't really make sense). Just typing the parameters directly does fix the issue.
I didn't close it because it still seemed like a bug? If not, feel free to close this out
ahejlsberg commentedon May 15, 2019
So, the reason it worked in earlier versions is because we failed to make any inferences for
PandFand just reverted to the constraints. With #29847 we now do make inferences forPandF. But because there is nothing discerning aboutPvs.F(other than constraints which aren't considered until after inference is finished) the inferences end up being poor. So, we now fail in a slightly different manner that causes an error. But, as I alluded to above, the type parameters should just be eliminated.