Allow negated types + F-bounded mapped types
dead-claudia opened this issue · 5 comments
Edit: keyof
works as I thought; mapped types are just broken in interfaces. I also clarified a few things.
Allowing negated types and F-bounded mapped type variables would solve several issues:
- Subtraction types: #4183 - The proposed
A - B
could be encoded asA & !B
as per this proposal. - Mapped conditional types: #12424 - For key-based conditions, this + F-bounded mapped types would allow that to be solved without explicit support.
- Promises - Having negated types makes it possible to prevent thenables from being used as generic Promise parameters.
Here's my proposal:
-
Allow negated types, using
!T
to represent the set of all types that do not conform toT
(i.e. not assignable toT
). This is pretty simple to digest. -
Expand mapped types to allow the key variable to be F-bounded, like in
{[P in Keys<T, P>]: ...}
.
The first is sufficient to cover subtraction types and Promise type issues, and the other two make mapped conditional types possible.
Big 👍 on the proposed syntax. I think the negation operator is indeed quite intuitive in the context of mapped types/keyof
and is a great idea. My only concern is that I'm not sure what it means outside of an intersection context. "Does not conform to T
" could be construed as meaning not assignable to T
which is very different from meaning not having any of the keys of T
. This may just need further clarification.
Minor nitpick, but I believe your second item is already valid today.
My only concern is that I'm not sure what it means outside of an intersection context.
This comment should explain type negation outside a union context (partial Promise fix).
"Does not conform to
T
" could be construed as meaning not assignable toT
which is very different from meaning not having any of the keys ofT
.
"not assignable to T
" is actually the intended meaning for negated types. This happens to be equivalent to "not having any of the keys of T
" in the context of object types, but it carries more expected semantics for primitives.
Minor nitpick, but I believe your second item is already valid today.
Yeah...I figured this out; I just ran into this odd bug.
I upvote A & !B
especially the !B
part... Over Exclude
from #21847
Automatically closing this issue for housekeeping purposes. The issue labels indicate that it is unactionable at the moment or has already been addressed.