-
Notifications
You must be signed in to change notification settings - Fork 12.6k
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
Wrong branch on conditional type with ReturnType of T condition #39364
Comments
Normally this is where I say "Ah, here's the subtle thing you missed", but... yeah that seems totally broken and I don't understand how it's been that way for so long without anyone else noticing? |
The root issue here is the way type ReturnType<T extends (...args: any) => any> = T extends (...args: any) => infer R ? R : any; As we're deciding whether to defer resolution of Changing the |
@ahejlsberg I would understand if |
@arogg Yes, ideally resolution of the type in your example would be deferred. However, it is surprisingly complex to devise rules that accurately measure whether an |
Looking at this a bit closer, where things go wrong is when we're relating the restrictive instantiation of |
Is this the same problem? type What<K extends string> =
{ x: { y: 0, z: 1 } } extends { x: { [P in K]: 0 } } ? true : false;
// What<K> is eagerly simplified to false before instantiation of K
type Huh = What<"y"> // expected: true, actual: false. I'm trying to figure out if the above should get its own issue filed or if it belongs on an existing one. From this SO question. |
@jcalz That appears to be a different issue. When determining whether to defer resolution of the conditional type we relate the "most permissive instantiations" of the check and extends types. The constraint of the most permissive instantiation of the extends type ends up being |
Looks like this got fixed along the way somewhere. Still other issues exist, but not sure if we should open a new one. |
I think I found a bug.
Last non-broken TS version for this is 3.1.6 on typescript playground. All later versions are broken.
Which gets me thinking: is this maybe intended behavior because it is "broken" for so many versions?
But i dont know why it should NOT be a bug. Either way if it's indeed not a bug, i need some serious brain rewiring from you guys please, because cant wrap my head around this behavior...
Let's get started
TypeScript Version: Nightly, all the way down to and including 3.3.3, tested with all these versions on playground
Search Terms: conditional types return type
Code
Expected behavior:
I expect number. Because [number] just cannot extend [string]
The TS handbook talks about deferred evaluation of conditional types. I seems it is not working here!! Evaluation of "ReturnType" should be deferred until the type is actually used in a concrete way!
Actual behavior:
The conditional type evaluates to string no matter what function type is passed in
Expected behavior:
I expect number, even the generic constaint now demands it!
Actual behavior:
Again, always get "string"
This is just for show, I expect number and get number, only difference is I now hardcode "number" instead of "ReturnType"
Playground Link: https://www.typescriptlang.org/play/?ts=Nightly#code/FAkFwTwBwUwAgMpgE4EsB2BzA8sgcgK4C2ARjMgDwAqcMAHmDOgCYDOcAFAJRwC8AfHACG6CIN5wA2gCUYYAsnRVoMavwC6tBkzZTWKDJnXA4cAPxx9aLCbgAuOOmJlkAbnAq4VGPr6IDWLiEpOQU3HyCTiHI-K5wAPTxcAD2ABaOyT4ANHAARFaGuaDAkLD+1jj4zuQATNRajCzs4QKO1TF+MnIKSipqmvSNupIFWMamFqOYtg5RLu4lnt76NX5IFUHtdS2R7bEJSWkZ2XlTRaCl8OuGm9EAzPWDOs08rXPk4lLvyAPaTXoBIy2SaAmZtaILS5eHxgO5rQG3FwPHbglz7RJwADGyWQyBgmLAOW+xRJQA
Related Issues: no, searched the issues
The text was updated successfully, but these errors were encountered: