Comments (13)
I don't see anything here that isn't addressed in other issues.
And hard to fix, as the mentioned issues are 5 to 7 years old, without being addressed, while it the issue seems quite real (TS seems to have a lot of such issues, it is kind of frustrating).
Every issue you encounter leads to an open issue rather than a closed one, interesting observation š
from typescript.
You didnāt provide any search terms.
Sorry for that, I was in a train with very slow/limited Internet access.
Also, āsurchargedā isnāt a term that makes much sense here but from context I gather you mean āoverloadedā.
Indeed, bad translation (in French we say "surcharge").
This is also in the documentation: Inferring Within Conditional Types
So according to the documentation :
When inferring from a type with multiple call signatures (such as the type of an overloaded function), inferences are made from the last signature (which, presumably, is the most permissive catch-all case).
The last signature being :
function foo(a: boolean|number)
Shouldn't Args
be at least [boolean|number]
?
It makes no sense for it to be sometimes the first signature, and sometimes the second signature.
from typescript.
You didnāt provide any search terms. Did you search for existing issues before filing this? Also, āsurchargedā isnāt a term that makes much sense here but from context I gather you mean āoverloadedā.
Duplicate #43731
from typescript.
This is also in the documentation: Inferring Within Conditional Types
When inferring from a type with multiple call signatures (such as the type of an overloaded function), inferences are made from the last signature (which, presumably, is the most permissive catch-all case). It is not possible to perform overload resolution based on a list of argument types.
from typescript.
"I was in a train" So, um, wait until you're off the train to file issues? Maybe? I don't know how to process this response.
"The last signature being" no, that's the implementation. It's not a call signature (try calling the function with Math.random()<0.5 ? true: 123
as an argument) If you want that call signature you need to add it explicitly.
from typescript.
If you want that call signature you need to add it explicitly.
Well, I don't want this to be a call signature, but the implementation signature to be used during inferences as it makes the most sense.
The documentation is also a little strange :
the last signature (which, presumably, is the most permissive catch-all case).
It is the implementation signature that is the catch-all case, not the last call signature.
from typescript.
The documentation refers to call signatures. You can't call the implementation signature. But I guess the wording could be clearer.
It is the implementation signature that is the catch-all case, not the last call signature.
That depends on your code. In your example there is no "catch-all" call signature. But you could add one:
function foo(a: boolean): void
function foo(a: number): void
function foo(a: boolean | number): void
function foo(a: boolean|number) {}
Now you have a catch-all call signature, and your function could be called with a value typed boolean | number
.
from typescript.
That depends on your code. In your example there is no "catch-all" call signature. But you could add one:
[...]
Now you have a catch-all call signature, and your function could be called with a value typedboolean | number
.
I think I see 3 issues for this.
The first one is that the third signature would be callable, so would enable to call e.g. foo(true, 3)
. When we only want this signature for inferences.
The second one is the code duplication between the last call signature and the implementation signature (code duplication is never a great thing).
The third one is that if we wish to use it on existing functions, we'd have to declare it for every functions which can be really time-consuming, with the risk of forgetting one, or if one function is modified, to forget to update the declaration.
Knowing that, without overload, TS already generates a signature from the implementation signature.
Could it be possible, with overload, to also generate one from the implementation (but non-callable) ?
For example, if we assume that TS generates a list of signatures, could we assume that e.g. the first one is non-callable (if other signatures are available), and reserve it for the implementation signature and inferences ? If empty (e.g. no implementation signature known), when doing inferences, could either use the last signature from the list (current behavior), or could even be computed as the union of the other signatures ?
Technically I'd assume this would be possible ?
from typescript.
So is this now some kind of feature request? TS is behaving as designed and weāre talking aboutā¦ implementation signature changes? Whatās the status of this as a bug report?
from typescript.
So is this now some kind of feature request? TS is behaving as designed and weāre talking aboutā¦ implementation signature changes? Whatās the status of this as a bug report?
Currently it seems the issue is a design issue. I think you consider them to be feature requests ?
from typescript.
I really don't know, and I'm not a member of the TS team, just a nosy annoying interested bystander, so nothing I say is authoritative. You can feel free to ignore me and just wait for the TS team to get involved. But, I'd say if you don't want this to be closed as just a duplicate of #43731 or others, you should edit it so it uses the feature request template and be specific and clear about what the feature request is, searching first for existing issues with similar requests, to help the TS team triage.
My guess is that they would just decline a suggestion to expose the implementation signature the way you're asking for. Function types don't encode implementation information, they encode call signature information. Declarations for overloads don't mention the implementation, and they shouldn't have to know anything about the implementation (or else TS's library files for JS would need to have all kinds of added information in them). And what good would it do to consult the implementation signature when the function is not callable that way? If you tell me Parameters<typeof foo>
is [boolean | number]
and I can't call foo(Math.random()<0.5?true:123)
then I'm not going to be happy. Personally I'd expect someone who runs into this discrepancy with overloads to ask for #14107 with the hope that you'd get [boolean] | [number]
or something like it.
Anyway I think I've said all I can say here so I will bow out and wait to hear what the TS team says. Good luck!
from typescript.
Thanks for your answer.
Personally I'd expect someone who runs into this discrepancy with overloads to ask for #14107 with the hope that you'd get
[boolean] | [number]
or something like it.
I agree. I assumed it was not possible as the doc stated:
It is not possible to perform overload resolution based on a list of argument types.
And hard to fix, as the mentioned issues are 5 to 7 years old, without being addressed, while it the issue seems quite real (TS seems to have a lot of such issues, it is kind of frustrating).
Indeed, as you stated :
If you tell me
Parameters<typeof foo>
is[boolean | number]
and I can't callfoo(Math.random()<0.5?true:123)
then I'm not going to be happy.
You are quite right. It is even more true if we have 2 arguments : [boolean | number, boolean | number]
, while you can't call foo(true, 0)
would indeed be incoherent.
However, I saw that the type has the different callable signatures :
type c = {
(a: boolean): void;
(a: number): void;
}
So TS seems to have all required information to perform a correct inference.
But I think I got the issue.
Possible solution 1:
For a simple inference, we could simply try it for each callable signature, and return an union of the inferred types.
But with more complex inference, we could have the same issue as you presented :
type Args<T> = T extends (a: infer A, b: infer B) => infer C ? [A,B, C] : never;
Could give [number|boolean, number|boolean, void]
. But it'd be technically correct as we didn't returned the function signature, but a tuple of the possible types for its parameters and return value.
Possible solution 2:
Else, the union could be made latter, by making an union of the results, e.g. returning : [number, number, void]|never|[boolean, boolean, void]
. But I assume it might pose some performances issues if there are lot of nested inference ?
Possible solution 3:
Adding to TS the types from the solution given inside the issue you just posted:
from typescript.
Every issue you encounter leads to an open issue rather than a closed one, interesting observation š
The interesting observation is that lot of theses issues are rather old than new, with multiples instances, and often due to design choices... some issues never got any clear answer whether they'll be fixed one day, its priority level, what prevent/delay a fix, etc.
I have so much fun wasting time on "unsound" stuff, and trying to find dirty workarounds if any.
from typescript.
Related Issues (20)
- [ServerErrors][JavaScript] 5.7.0-dev.20240904 vs 5.5.4 HOT 13
- [ServerErrors][TypeScript] 5.7.0-dev.20240904 vs 5.5.4 HOT 18
- Removing optional modifier in homomorphic mapped types does not work in generic contexts since 5.5.x
- function members of primitives/builtins are not read-only HOT 6
- TypeScript 5.7 Iteration Plan HOT 1
- Iterator Helpers Typing HOT 7
- Template Literal Types derived from the type keys cannot be used as Indexed Access Types in generic contexts HOT 3
- Buffer type incompatibility with BinaryLike | KeyObject in crypto.createHmac() function HOT 4
- function object parameter destructure field without default value will be ignored HOT 3
- Compiler doesn't warn about incompatible signatures HOT 2
- GitHub Issue Duplicate Detector HOT 2
- Template literal type derived from string is not a subtype of the TLT derived from any
- Improve Iterator Helper Type Signatures HOT 10
- Missing Handbook Content HOT 3
- Suggest @ts-expect-error as Quick Fix
- @import suggestions for auto-imports in VS Code
- Binding element incorrectly reported as having `any` type in JS with JSDoc starting with 5.6.2 HOT 3
- React's ComponentProps type issues in TypeScript 5.6.2 HOT 11
- The function type should not inherit the built-in object type HOT 3
- Ability for compiler host to provide resolution mode for file and say it supports impledNodeFormat HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
š Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. ššš
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ā¤ļø Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from typescript.