-
Notifications
You must be signed in to change notification settings - Fork 12.5k
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
Generic intersection is not sufficiently narrowed for assignment to conditional type of the same. #32591
Comments
This looks to be working as designed.
Constraints for type parameters are intentionally ignored when resolving conditional types. The fundamental reason for this is because assignability is not transitive and therefore using the constraint of a type parameter can introduce unsound simplifications. A trivial example: type Example<T extends [any]> = T extends [number] ? true : false;
/**
* The constraint of `T` in Example is always assignable to the extends
* type, but we can create unassignable instantiations.
*/
type Example1 = Example<[boolean]>; // false TypeScript choose false negatives (as in your case) over false positives.
Once non-simplification of the conditional type is assumed the error messages follows from the checker trying to relate a type parameter to some type by relating its constraint to the type. |
I agree with your example that type Example<T extends [number]> = T extends [any] ? true : false then I don't believe there is any possible generic instantiation of Perhaps I'm misunderstanding the issue with assignability not being transitive. Is there some design issue that makes it so the type checker can't narrow the generic type by what it extends when evaluating a conditional type? |
TypeScript wont even try and simplify distributive conditional types like: type Example<T extends [number]> = T extends [any] ? true : false probably because in the general case it's very hard to get right. If If you change the type to: type Example2<T extends [number]> = [T] extends [any] ? true : false then this will simplify to
Your example is a specific case, but the checker works in general cases. Roughly the form would be something like: Given
If the constraint of
Assignability is not transitive for various reasons therefore the checker does not use this reasoning. In your specific example |
For those who come after me, it appears the piece of the puzzle that I was missing is that I would love to see this addressed in some way. Reading over some other GitHub issues (now that I know what to search for) it sounds like there are some thoughts on this though I don't see an obvious place where discussion on the topic is happening. Those few narrowing assignment situations certainly are frustrating since they prevent this type of thing from working. I'm guessing it is too much to hope for the compiler being "smart" about which generic constraints can safely be transitive in a conditional, and which ones cannot? |
You shouldn't think of It's more of a turn-off-type-checking type |
FWIW I think this is a duplicate of #23132. |
Thanks as usual for the excellent discussion getting to the bottom of this, everyone |
This issue has been marked as a 'Duplicate' and has seen no recent activity. It has been automatically closed for house-keeping purposes. |
TypeScript Version: 3.6.0-dev.20190727
Search Terms:
generic is not assignable to conditional
Code
Expected behavior:
T
(whichextends string
) to be assignable toT extends string ? T : never
.Actual behavior:
I have no idea why the type checker is trying to assign
param
as astring
. The error is correct in what it states, which is thatstring
is not assignable toT extends string ? T : never
becausestring
is not assignable to eitherT
ornever
. However,param
is aT
, not astring
andT
should be assignable toT extends string ? T : never
unless that evaluates tonever
. Since the generic type definition forT
isT extends string
we can assert that theT extends string
conditional statement must always be true. Therefore,T extends string ? T : never
can never evaluate tofalse
, thus it can never benever
.Playground Link: Playground
Related Issues:
Maybe the following, though I don't really grok root cause so I'm not sure:
#30152
#29939
The text was updated successfully, but these errors were encountered: