Skip to content

Design Meeting Notes, 5/5/2023 #54227

Closed
Closed
@DanielRosenwasser

Description

@DanielRosenwasser

Deferring Indexed Access

#53970

  • 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 of K can change the outcome if SomeType is actually a union where each constituent can be discriminated on kind.
    • 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 some T that mostly acts as never.
    • That marker should act as a normal literal type.
  • 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

#26349

  • 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 _.
  • 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 named Foo, 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

#54143

  • [[Out of time?]]

Metadata

Metadata

Assignees

No one assigned

    Labels

    Design NotesNotes from our design meetings

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions