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
Instantiation expressions don't filter signatures with non-matching constraints #51694
declarefunctionfoo<TextendskeyofHTMLElementTagNameMap>(arg: T): HTMLElementTagNameMap[T];declarefunctionfoo<TextendsHTMLElement>(arg: T): T;typeFirstFoo=typeoffoo<"div">;// Type 'string' does not satisfy the constraint 'HTMLElement'.(2344)
🙁 Actual behavior
This instantiation expression errors despite the fact that a matching signature exists.
🙂 Expected behavior
It sounds likely that most people would assume that this should work similarly to how overloads are chosen - but instead an intersection is being created based on all signatures with the same type arguments arity.
IIRC what I’ve seen when debugging this - it’s an intersection, it’s not picking a single matching signature.
I think that it makes sense per the second part of this comment: #51695 (comment) . It’s just that when mapping those signatures reportErrors was always set to true and non-matching signatures were not rejected
I went back to recheck the implementation, "intersection" definitely caught my eye somewhere around this code but it seems that it was in some different parts.
What would need to happen from the TypeScript team perspective for this change to be accepted? It seems to be a very reasonable improvement and it also addresses a couple other problems (linked above).
in my specific case, i can use the arity "hack" (together with generic type defaults to not impede other usages that want to specify the "non-hack" type params), but it does not look very nice
Activity
fatcerberus commentedon Nov 30, 2022
Is it that, or is it just picking the last overload, similar to what happens with
Parameters?Andarist commentedon Nov 30, 2022
IIRC what I’ve seen when debugging this - it’s an intersection, it’s not picking a single matching signature.
I think that it makes sense per the second part of this comment: #51695 (comment) . It’s just that when mapping those signatures
reportErrorswas always set to true and non-matching signatures were not rejectedAndarist commentedon Dec 1, 2022
I went back to recheck the implementation, "intersection" definitely caught my eye somewhere around this code but it seems that it was in some different parts.
So this isn't actually becoming an intersection, but the effect is kinda similar - it's an object type with multiple signatures (and more):
https://github.dev/microsoft/TypeScript/blob/70d5cb28275d35e45a0f84aa981b45e6fb059160/src/compiler/checker.ts#L33667-L33679
RyanCavanaugh commentedon Dec 2, 2022
Anders Hejlsberg (@ahejlsberg) any thoughts?
apendua commentedon Aug 23, 2024
What would need to happen from the TypeScript team perspective for this change to be accepted? It seems to be a very reasonable improvement and it also addresses a couple other problems (linked above).
CSharpFiasco commentedon May 4, 2025
Any progress on this? Just encountered it and it'd be nice to have
backbone87 commentedon Oct 8, 2025
this feature does not play nicely at all with overloads:
would expect
[arg: number | string]or more likely[arg: string] | [arg: number]the only "filtering" behavior on signatures is based on generic arg arity:
in my specific case, i can use the arity "hack" (together with generic type defaults to not impede other usages that want to specify the "non-hack" type params), but it does not look very nice