Closed
Description
Deferring Indexed Access
- Cute trick to emulate higher kinded types.
- In Defer resolution of indexed access types with reducible object types #53098, we changed our logic to say that we defer indexed access types on stuff like
(SomeType & { kind: K })[K]
because an instantiation ofK
can change the outcome ifSomeType
is actually a union where each constituent can be discriminated onkind
.- But in this case, there is definitely no discriminant.
- Idea: we still defer, but only if [[some condition - come back to this]] in
isGenericReducibleType
.- For
{ kind: "foo" } & { kind: T }
, it uses a marker type for someT
that mostly acts asnever
. - That marker should act as a normal literal type.
- For
- Is it the case that we "technically support higher kinded types" through this?
- No - this is just a technique for accomplishing something like this.
- We "support it" in so far as we support any arithmetic in the type system.
- But it doesn't accomplish what users are usually talking about when they mention HKTs.
Partial Inference with Partially Filled Type Argument Lists
- Doing inference just on all missing type arguments doesn't work well because it affects overload resolution.
- Unfortunately produces very undesirable results.
- Idea: use an underscore (
_
) as a signal for this.- Lots of languages use this - Rust, F#, Flow.
- Can still have a type named
_
.- Context sensitive - in a type argument position, this means "infer this"
- Who the heck uses
_
as a type anyway?- We could reserve it. Don't have to.
- Could deprecate it.
- We could force users to disambiguate.
- Would become IMPOSSIBLE if some jerk shipped a single global type named
_
.
- Would become IMPOSSIBLE if some jerk shipped a single global type named
- Still have to write out a bunch of
_
- gut feel for if people are willing to still take that? - Does this make all type arguments effectively optional?
- No, that's the point - always need a full type argument list.
- Only can be used on invocations of type argument lists.
- Anywhere we can do inference.
- Maybe issue a specific error if someone tries to write an unresolved
_
anywhere else.
- Will be irritating when people use trailing type arguments for computed names within their type.
- So maybe we need some sort of local type declaration.
- But the problem is you need this for an entire signature - not just a type.
- For example if you wrote
<T>(x: Foo<T>) => Foo<T>
, and you needed to define a local type alias namedFoo
, where would you do it?-
Can't be
<T>(x: Foo<T>) => let Foo<T> = ... in Foo<T>
-
Can't be
<T>(x: let Foo<T> = ... in Foo<T>) => Foo<T>
-
Could be
<T>(x: Foo<T>) => Foo<T> where Foo<T> = ... in Foo<T>
- Mixed reaction - can't get auto-completion from this now.
-
- Conclusion: let's try to land it in 5.2!
Type guard incorrectly erases union type
- [[Out of time?]]