Skip to content

Design Meeting Notes, 12/10/2021 #47151

Closed
@DanielRosenwasser

Description

@DanielRosenwasser

"Correlated Union Types"

#30581

type NumberRecord = { kind: "n", v: number, f: (v: number) => void };
type StringRecord = { kind: "s", v: string, f: (v: string) => void };
type BooleanRecord = { kind: "b", v: boolean, f: (v: boolean) => void };
type UnionRecord = NumberRecord | StringRecord | BooleanRecord;

function processRecord(record: UnionRecord) {
  record.f(record.v); // error!
 // error msg in TS3.2 and below: can't call union of functions
 // error msg in TS3.3 and up: record.v not assignable to never
}
  • We want to be able to feed the callback with the original value; but now v is a union type and f's parameter type is an intersection; that's not precise for v, and that intersection now only accepts never.

  • People have speculated that maybe we need existential types so that we can say "this function takes whatever type v has" and can feed it through.

  • Can try to re-model this in the form of a re-indexed mapped type.

    interface TypeMap {
        "n": number;
        "s": string;
        "b": boolean;
    }
    
    type UnionRecord<P extends keyof TypeMap> = { [K in P}]: {
            kind: K;
            v: TypeMap[K];
            f: (p: TypeMap[K]) => void;
        }
    }[K];
    
    function processRecord<K extends keyof TypeMap>(record: UnionRecord<K>) {
        record.f(record.v);
    }
  • With some improvements of inference and apparent types, we can enable most of these cases - 2 improvements on the scale of what feel like bug fixes.

    • First is inference to the IIFE-like mapped object pattern from above.
    • Second is how we present the apparent members of certain types when you index into an already-instantiated mapped object type (a "table type") with some generic key.
      • { [P in K]: Foo<P> }[X] => Foo<X>
      • Does that mean that if you aren't using a type that was declared as a mapped type, then we won't get a more precise type?
        • Yes, if you leave off types on these objects.
          • I guess we don't have an easy way to correlate.
          • We could try to do something there...but that's a bit of a stretch.
  • This is a weird pattern. Would like to not have to teach people to write this.

Modules Migration Status Update

#46567

  • A lot of time running tests.
  • A lot of time is going into getters for every single binding.
  • Had TypeScript generate to CJS, had esbuild run on top of that.
  • Swapped TS to generate ESM, and esbuild generates the same sorts of bindings - so no optimization there.
  • 25 minutes to run the full tests! Thanks to the multiple levels of indirections of calling functions.
  • Could switch to ES3 emit to avoid accessors.
  • Also could switch to native ESM emit.
    • No telling how slow ESM live bindings would be.
  • Could avoid indirect barrel imports.
  • Looked at bundler front-ends that are largely esbuild wrappers.
    • But these tend to push for the optimized build to use Rollup.
  • [[Whole discussion on what the right shipping format and layout to send.]]
  • Dogfooding with modules showed us just how slow this is.
  • Conclusion
    • Investigate the __createBindings issue.
    • Investigate alternative bundlers.

Ensuring Modules Conform to a Type

#38511

  • Lots of people would like to be able to ensure "this file has this sort of shape."
    • Then "I would like this folder to describe this shape".
  • export implements SomeType that
  • PR suggests everything should be contextually typed.
  • You can emulate this today with a self-import.
    • Without contextual typing, this is possibly just sugar that saves you 2 lines. Maybe not as compelling.
  • This links to typing default exports - is that the real feature?
  • Out of time - revisit in the new year.

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