-
Notifications
You must be signed in to change notification settings - Fork 12.8k
Unrelated overload signature affects inference #25917
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
Comments
I'm actually seeing |
This is a design limitation of how overload resolution is implemented. when the compiler is trying to resolve overloads it goes through them in order one at a time trying to see which is a fit. The arguments to the function can be "contextually sensitive", i.e. their type depends on the containing context, for instance function expressions or object literals. in this case the compiler will try to infer a contextual type to go with the function expression. the type is then used to contextually type the function expression, and then check the body of the function to infer the return type. if that fits, then good, the signature is picked, if that does not the compiler moves on to the next overload. the issue here is once a function expression gets a contextual type, there is no going back. the compiler can not just remove the type and recheck it (that is not how it is implemented). so what happens is that the next overload will have the same contextual type from the previous overload, ( A better implementation of overload resolution would be one that can erase contextual types, and try others without side effects. this, however, is a tantamount to a complete rewrite to the overload resolution logic, and has some drastic impacts on performance. |
@Andy-MS The behaviour is sensitive to the compiler options mentioned in the issue: "strictFunctionTypes": true,
"strictNullChecks": false For example, if |
@mhegazy Why is the behaviour different - with |
I am not seeing that on the latest version of the compiler. |
Apologies. I thought that VS Code used the local version of TypeScript - as that's what the linting extension does. I can see now that I was wrong. (In fact, the TS version used by VS Code is indicated in the toolbar.) I created a small compiler API harness and the behaviour's dependency on the compiler-options appears to have been addressed in version 3.0, as the |
In fixing a problem with the typings for the RxJS
first
andlast
operators, I've stumbled across some weird behaviour with overload signatures.TypeScript Version:
next
(3.1.0-dev.20180725)Search Terms:
overload signature inference unrelated incorrect
Code
For the behaviour to be effected,
strictFunctionTypes
must betrue
andstrictNullChecks
must befalse
:Expected behavior:
When passing a function that is not a user-defined type guard, I'd expect the inferred type to be independent of whether or not the type-guard-accepting overload signature is available or is commented out.
Actual behavior:
However, if the signature that accepts a type guard is available, the inferred type - for a call that does not involve a user-defined type guard - will be:
And if the signature that accepts a type guard is commented out, the inferred type - for a call that does not involve a user-defined type guard - will be:
In RxJS, this causes a problem when the operators are used with
pipe
. If a return type with a string literal is inferred - e.g.MonoTypeOperatorFunction<"s">
- an error will be effected if the operators are used with astring
source, asstring
won't be assignable to"s"
.Also, why is the behaviour dependent upon the above-mentioned compiler options? In particular, why does it depend upon the
strictNullChecks
option?Related Issues: None found.
The text was updated successfully, but these errors were encountered: