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
Type inference fails with complex generic tuples #4136
I've been trying to come up with a smarter type def for Angular's $q.all (https://docs.angularjs.org/api/ng/service/$q#all) which takes an array of promises and spits out a promise with an array of results as the value.
For reference, the current DefinitelyTyped implementation is:
all(promises: IPromise<any>[]): IPromise<any[]>;
I'm attempting to rewrite it with tuples, like so:
// Fails type inference, causes errorvara=$q.all([$q.when<string>(),$q.when<number>()]);// Explicit types work finevarb=$q.all<string,number>([$q.when<string>(),$q.when<number>()]);// Same generic type works finevarc=$q.all([$q.when<string>(),$q.when<string>()]);
Attempting to use this with multiple different implicit generic types (example a) causes this error:
The type argument for type parameter 'T1' cannot be inferred from the usage. Consider specifying the type arguments explicitly. The argument candidate 'string' is not a valid type argument because it is not a supertype of candidate 'number'.
As far as I can tell, the Typescript compiler should (ideally) be able to infer this fine. The error seems wrong: 'number' shouldn't be a candidate for T1 at all.
We currently treat tuple types like any other object type in type inference. Tuples are basically arrays with extra numerically named members for the elements and a union of the tuple types as the array element type. It is this union that messes up type inference: Instead of inferring string for T1 and number for T2, we end up inferring both string and number for both T1 and T2. This also explains why it works when T1 and T2 are the same type.
It's fairly easy to fix, we just need to special case tuple-to-tuple inference and not dive into the structure of the types as we do now.
Activity
ahejlsberg commentedon Aug 4, 2015
We currently treat tuple types like any other object type in type inference. Tuples are basically arrays with extra numerically named members for the elements and a union of the tuple types as the array element type. It is this union that messes up type inference: Instead of inferring
stringforT1andnumberforT2, we end up inferring bothstringandnumberfor bothT1andT2. This also explains why it works whenT1andT2are the same type.It's fairly easy to fix, we just need to special case tuple-to-tuple inference and not dive into the structure of the types as we do now.