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
Contextual narrowing fails inside thunked argument when T is inferred from a separate argumentΒ #63511
typeColor='red'|'blue';typeCarrier<T>={__t?: (x: T)=>void};declarefunctiondirect<T>(c: Carrier<T>,opts: {colors: readonlyT[]}): T;declarefunctionthunked<T>(c: Carrier<T>,opts: ()=>{colors: readonlyT[]}): T;constc=nullasunknownasCarrier<Color>;direct(c,{colors: ['red']});// β narrows: T = Colorthunked(c,()=>({colors: ['red']}));// β string[] not assignable to readonly Color[]
π Actual behavior
T is inferred as Color from Carrier<T> in both calls. In the thunked form the nested array literal ['red'] widens to string[] before contextual typing reaches it from readonly T[], producing Type 'string' is not assignable to type 'Color'.
π Expected behavior
The thunked form narrows the same way as direct: ['red'] is contextually typed against readonly Color[] and the call type-checks. The two forms differ only in whether the options are bound directly or via an arrow function β the inferred T is the same.
Additional information about the issue
The pattern matters for reactive-resource wrapper libraries (e.g. glimmer-apollo) that require args to be wrapped in a function so they can re-evaluate when tracked state changes. The thunk shape is idiomatic; the inference asymmetry forces consumers to scatter as const casts across nested literals.
changed the title [-]Contextual narrowing of nested array literal fails inside arrow returning a tuple[/-][+]Contextual narrowing fails inside thunked argument when T is inferred from a separate argument[/+]on May 28, 2026
Activity
[-]Contextual narrowing of nested array literal fails inside arrow returning a tuple[/-][+]Contextual narrowing fails inside thunked argument when T is inferred from a separate argument[/+]MartinJohns commentedon May 28, 2026
Duplicate of #241.
johanrd commentedon May 28, 2026
Martin Johns (@MartinJohns) thanks