Closed
Description
Conditional Types
- Last time, we needed an idea of when to defer the evaluation of each branch of a conditional type.
- Idea:
- spread over unions, if you have
any
ornever
, you create a union (since you have no idea where anything will go) - If the type is assignable, go to the true branch's type.
- Otherwise, check whether the type is not possibly assignable, then go to the false branch's type.
- Type parameters imply the possibility of assignability - erase them to
any
.- What about
never
instead ofany
?any
works better for contravariant positions.
- What about
- Uses
typeMaybeAssignableTo
which is like comparability but only at the top-level.- Should probably be a new type relationship.
- Why not use comparability?
- Ehh, not quite the same.
- Type parameters imply the possibility of assignability - erase them to
- What happens when you can't make a definitive statement about either case?
- We have to put in some new concepts of how to relate these types.
- spread over unions, if you have
- Also: new internal type called a substitution type.
- In
T extends string ? [[A]] : [[B]]
, you wantA
to act as something that is also astring
in[[A]]
.
- In
type Diff<T, U> = T extends U ? never: T
Core idea here is that in each branch, once the condition can be "evaluated", T
is re-bound to each constituent if the original T
was instantiated with a union type.
Means that
interface Box<T> {
element: T;
}
type BoxEverything<T> = T extends any ? Box<T> : never;
// Same as 'Box<number> | Box<string> | Box<boolean>'.
type Foo = BoxEverything<number | string | boolean>;
-
Should
T
refer to the original type, or just the constituents?- Well, we could say that users need to make distribution over unions explicit.
- Would need a syntax for iteration over unions.
P in T: P extends U ? P : never
- We've very rarely not wanted the current behavior that automatically distributes over unions.
-
Seems like we want to do this!
- Types continue operating on the principle of distributing over unions. We should find ways to communicate this to our users.
- But wanting mapping, seems like we'd want to
-
Do we want to add the helpers to the standard library?
- Definitely
Diff
.- But it doesn't actually have the ability to negate assignability.
- What about
If
,Not
,And
, andOr
?- "Yeah, but who's gonna use them?"
- "Uhh...", [[collective laughter implying that somebody will use these for something crazy]]
- What about
NonNullable
?- That leads us to the next topic.
- "Yeah, but who's gonna use them?"
- Definitely
Narrowing type parameter constraints
- Want to narrow the constraint of a type parameter from
number | undefined
tonumber
.- Conclusion: Experiment with offline.
Variadic Types
- 13 minutes left in the design meeting, we can't reasonably go over this.
Optionality: missing
and undefined
-
Comes up very frequently in React's
setState
API.- Users say "you should be able to pass in a subset of the properties in
T
(i.e.Partial<T>
, meaningT
but all optional) but you shouldn't be able to pass inundefined
. - Currently the type system doesn't know how to differentiate these cases.
- Users say "you should be able to pass in a subset of the properties in
-
Today, the type hierarchy looks something vaguely like
any / | \ {} null undefined
-
Could imagine a new subtype of
undefined
calledmissing
!any / | \ {} null undefined | missing
-
undefined
is not assignable tomissing
, but the opposite is true. -
Optionality implies unioning the type with
missing
.interface Foo { x?: number; // implicitly has the type 'number | missing'. }
-
Note! We don't want
any
to be assignable tomissing
!any
continues to be the top type (missing
is assignable toany
...) but is no longer quite the bottom type with respect to assignability (any
is not assignable tomissing
!).never
continues to be the true bottom type, assignable tomissing
and everything else.
-
This would definitely be a breaking change.
- What would
Partial
become?- Might need an
Optionalize
orSubset
or whatever.
- Might need an
- What would
-
What about parameter types?
- Often need to communicate optionality from a set of parameters to another set of parameters.