Skip to content

Design Meeting Notes, 5/19/2017 #15957

Closed
Closed
@DanielRosenwasser

Description

@DanielRosenwasser

Inference/Generic function composition requests

Issues linked to at the bottom.


  • Why are we revisiting this?
    • Ben from RxJS filed an issue about general inference difficulties.
    • Will also be important for function pipeline in the future if it lands in ES.
  • Currently we use inferences from values to flow into function parameters
  • But we don't use the type that the result will flow into for inferences.

Example

type Mapper<T, U> = (x: T) => U;

function wrap<T, U>(cb: Mapper<T, U>): Mapper<T, U> {
    return cb;
}

function wrapStringToNumber(cb: Mapper<string, number>): Mapper<string, number> {
    return cb;
}

// works (not wrapped in a call)
let f1: Mapper<string, number> = s => s.length;

// works (types are concrete)
let f2: Mapper<string, number> = wrapStringToNumber(s => s.length);

// doesn't work because there are no parameters with known types
let f3: Mapper<string, number> = wrap(s => s.length);

What you'd like in the last example is that wrap(...) draws inferences from its contextual type.

But there are some problems with just using the contextual type.

// This works
let a1 = ["a", "b"].map(s => s.length);

// This doesn't - requesting the contextual type of `map`'s argument "fixes"
// its type parameters which don't have any inferences. This means that `s` gets the right type,
// but `a2` gets the type `Array<{}>`!
let a2 = ["a", "b"].map(wrap(s => s.length));

So basic idea for solution.

  1. Draw inferences from arguments that are not contextually sensitive (e.g. values that are not untyped lambdas that we could give types to).
  2. During the second round of inference...
    • if we run into a a contextually sensitive argument...
    • which needs a type parameter which has no inferences...
    • then reach out of the call and make inferences from the contextual type to the call's return type

Harder stuff involves inference between generic type parameters.
Not clear what to do here, but we can tackle it one step at a time.


Default imports for CommonJS modules

Want to align with Babel's emit - very difficult when people transition to using TypeScript and have to change their imports.

Biggest problem is that no way to tell which is "more correct" when you have a .d.ts that has top-level exports - is that a CJS or is it an ES module authored on top of CJS?

Entire thing needs a proposal.


Issues for Composition (instantiate generic signatures using contextual type instead of any)

Open:

Duplicates:

Inference from return type position

Higher order inference with generic functions

Comparing generic signatures

Open:

Duplicates:

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