-
Notifications
You must be signed in to change notification settings - Fork 12.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Avoid getting single call signatures when parameter types are the same #58392
Avoid getting single call signatures when parameter types are the same #58392
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just curious, did you determine which part of the skipped logic is actually causing the circularity?
@@ -20770,6 +20770,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { | |||
const sourceType = i === restIndex ? getRestOrAnyTypeAtPosition(source, i) : tryGetTypeAtPosition(source, i); | |||
const targetType = i === restIndex ? getRestOrAnyTypeAtPosition(target, i) : tryGetTypeAtPosition(target, i); | |||
if (sourceType && targetType) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Change to sourceType && targetType && sourceType !== targetType
and get rid of the conditional continue
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done :) thanks for pointing out
src/compiler/checker.ts
Outdated
if (sourceType === targetType) { | ||
continue; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not super fond of this as a fix. It could be treated as a potential perf optimization~ - although I really doubt it would show anything in the perf runs, it's just an early bailout from this loop. It just happens to fix this particular circularity.
Similar bailouts are used in a couple of places in the code (even at the top of the containing function - compareSignaturesRelated
).
Ideally, I'd just like to recognize this type as one without call signatures so it could be typechecked using regular rules. At first, I thought that this code could just be simplified for the scenarios with strictVariance
- after all, if we already have strict variance on why do we need to special case anything here?
It turns out though that despite strict variance the callback parameters are still special - even if they are bivariant methods (!). This is somewhat surprising and I just learned about it today, while working on this but I guess it makes sense. Covariant type checking for callback parameters was introduced here. You can also see what changed when I tried to ignore this logic here
The problem arises on main
because both getNonNullableType
and getSingleCallSignature
resolve properties of the type and both are called to learn if the parameter is a callback parameter.
In this specific case, I could also experiment with:
- avoiding transitive
resolveStructuredTypeMembers
ingetTypeFactsWorker
based oncallerOnlyNeeds
. if the caller only needs to learn if the type is nullable or not... we don't need to check if it's a function type to compute those facts - avoiding
resolveStructuredTypeMembers
ingetSingleSignature
whenSignatureKind.Call
is requested and the type's symbol has aSymbolFlags.Class
. If the type is a class then it has a construct signature (and thusgetSingleCallSignature
can't returntrue
in such a case) so the code could bail out early.
Some extra consideration for unions/intersections could be put into the above too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cc @ahejlsberg - i was elaborating on this down here when u asked the question about what exact code has caused this ;p
…call-signature-for-same-param-types
Any idea if this will land in 5.5? |
@typescript-bot test it |
Hey @jakebailey, the results of running the DT tests are ready. Everything looks the same! |
@jakebailey Here are the results of running the user tests comparing Everything looks good! |
@jakebailey Here they are:
tscComparison Report - baseline..pr
System info unknown
Hosts
Scenarios
Developer Information: |
@jakebailey Here are the results of running the top 400 repos comparing Everything looks good! |
fixes #58391