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
functionfunc<T1,T3extends{[key: string]: (context: T1)=>void},T4={},// Commenting out this section of code makes it work properly.>(data: {T: T1;K: T3&ThisType<T1&T3>;}){}func({T: {bbb: 123,aaa(){return333;},},K: {bbb(context){console.log(context.aaa());console.log(context.bbb);this.ccc();},ccc(){},},});
π Actual behavior
display an error message:
'context' is of type 'unknown'.
'context' is of type 'unknown'.
'T4' is declared but its value is never read.
'data' is declared but its value is never read.
π Expected behavior
The type of 'context' should already be determined; it shouldn't be 'unknown'.
The problem is the following if inside instantiateContextualType:
// If no inferences have been made, and none of the type parameters for which we are inferring// specify default types, nothing is gained from instantiating as type parameters would just be// replaced with their constraints similar to the apparent type.if(inferenceContext&&contextFlags!&ContextFlags.Signature&&some(inferenceContext.inferences,hasInferenceCandidatesOrDefault)){// For contextual signatures we incorporate all inferences made so far, e.g. from return// types as well as arguments to the left in a function call.returninstantiateInstantiableTypes(contextualType,inferenceContext.nonFixingMapper);}
The condition results true at the wrong time, too eagerly as far as I understand it, therefore stuff gets instantiated with some default types.
If you change the condition in one of the two following ways you solve this specific issue, but you get failing baselines:
!some(inferenceContext.inferences, hasInferenceCandidatesOrDefault) seems somewhat more related with the above comment (?), but you get too many failing baselines
every(inferenceContext.inferences, hasInferenceCandidatesOrDefault) just a couple of failing baselines, but one of them is about contextual inference and, guess what, it works here but not there anymore
This seems to have been fixed by TypeScript 6.0. The provided example no longer errors and context is now inferred as { bbb: number; aaa(): 333 }. I'm guessing that #62243 did the trick.
This is fixed by PR #62243. The original object-literal method form produced context: unknown and TS2339 errors in 5.9.3 and 6.0.0-dev.20251210; it is clean from 6.0.0-dev.20251211, including 6.0.3 and the current native compiler.
Activity
[-]generic type inference failed[/-][+]Generic type inference failed[/+]jfet97 commentedon Jan 3, 2024
The following seems to work:
Playground
Andarist commentedon Jan 4, 2024
This likely belongs to this umbrella issue: #47599
jfet97 commentedon Jan 4, 2024
The problem is the following
ifinsideinstantiateContextualType:The condition results
trueat the wrong time, too eagerly as far as I understand it, therefore stuff gets instantiated with some default types.If you change the condition in one of the two following ways you solve this specific issue, but you get failing baselines:
!some(inferenceContext.inferences, hasInferenceCandidatesOrDefault)seems somewhat more related with the above comment (?), but you get too many failing baselinesevery(inferenceContext.inferences, hasInferenceCandidatesOrDefault)just a couple of failing baselines, but one of them is about contextual inference and, guess what, it works here but not there anymoremkantor commentedon Jun 8, 2026
This seems to have been fixed by TypeScript 6.0. The provided example no longer errors and
contextis now inferred as{ bbb: number; aaa(): 333 }. I'm guessing that #62243 did the trick.RyanCavanaugh commentedon Sep 19, 2026
This is fixed by PR #62243. The original object-literal method form produced
context: unknownand TS2339 errors in 5.9.3 and6.0.0-dev.20251210; it is clean from6.0.0-dev.20251211, including 6.0.3 and the current native compiler.