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
Generic inference different between equivalent function expression and shorthand method in object literal #32230
Search Terms: parameter, inference, order, generic, function expression, function declaration
Code
typeCallback<TFoo,TBar>=(foo: TFoo,bar: TBar)=>anydeclarefunctionexample<TFoo,TBar,TCallbackextendsCallback<TFoo,TBar>>(foo: TFoo,callback: TCallback,bar: TBar,): TCallback// bar is infered to be 'string'example(42,(foo,bar)=>({t: ()=>{}}),'42')// bar isn't infered and is 'unknown'example(42,(foo,bar)=>({t(){}}),'42')
Expected behavior: foo and bar should be inferred as number and string respectively in both cases
Actual behavior:
When not using arrow function expression bar is not inferred, even though foo is infered in both cases
Related Issues: This code worked in TS 3.3.3 , so #31814 is most definitely related, and so probably #30215 is the root cause. #6627 is somewhat related.
Comment: Type inference stops working for types which appear in arguments after inner call to a generic function when function declaration appears in callback return. Using function expressions instead is limiting because those does not have correct this context.
Is this behavior caused by the same limitations as #31814, or is it something what can be improved?
changed the title [-]Generic type inference fails when using function declaration, and does not when using function expression[/-][+]Generic inference different between equivalent function expression and shorthand method in object literal[/+]on Jul 3, 2019
This issue is somewhat involved. The core issue is cache invalidation during type inference. Specifically, when we make new inferences for a particular type parameter we only invalidate the cache for that type parameter. In the example above, TCallback indirectly depends on inferences for TFoo and TBar because, when we have no candidates for TCallback, we default to the constraint Callback<TFoo, TBar>. This may cause us to cache an inference for TCallback based on the current inferences for TFoo and TBar and then not recompute when new inferences are made for TFoo and TBar.
I think the fix is to invalidate all caches for non-fixed type parameters when inferences are made for a particular type parameter in an inference context. I will look into it.
Activity
RyanCavanaugh commentedon Jul 3, 2019
Nit: These are shorthand method definitions, not function declarations.
This doesn't seem correct.
examplecould beIn which case the first call will definitely observe
foo === 42.RyanCavanaugh commentedon Jul 3, 2019
Anders Hejlsberg (@ahejlsberg) I might be missing something but I don't see any reason for the two to behave differently
[-]Generic type inference fails when using function declaration, and does not when using function expression[/-][+]Generic inference different between equivalent function expression and shorthand method in object literal[/+]minajevs commentedon Jul 4, 2019
Thanks, I had a hard time finding correct name for that.
Oh yeah, I described it poorly. Changed it to "
fooandbarshould be inferred as number and string respectively in both cases"minajevs commentedon Jul 11, 2019
I am trying to investigate it myself. This bug appears after this commit. Why exactly non-fixing mapper causes that I am yet to find.
ahejlsberg commentedon Jul 11, 2019
This issue is somewhat involved. The core issue is cache invalidation during type inference. Specifically, when we make new inferences for a particular type parameter we only invalidate the cache for that type parameter. In the example above,
TCallbackindirectly depends on inferences forTFooandTBarbecause, when we have no candidates forTCallback, we default to the constraintCallback<TFoo, TBar>. This may cause us to cache an inference forTCallbackbased on the current inferences forTFooandTBarand then not recompute when new inferences are made forTFooandTBar.I think the fix is to invalidate all caches for non-fixed type parameters when inferences are made for a particular type parameter in an inference context. I will look into it.