Skip to content

Design Meeting Notes, 6/2/2017 #16414

Closed
Closed
@DanielRosenwasser

Description

@DanielRosenwasser

Propagated Inference for Uninstantiated (Free) Type Parameters (#9366)

function compose<A, B, C>(f: (x: A) => B, g: (y: B) => C): (x: A) => C {
    // ...
}

let boxElements: (a: string) => { value: string[] } =
    compose(x => [x], y => { value: y });

Currently this works.

Now we ask, what if we wanted boxElements to operate on any type?

function compose<A, B, C>(f: (x: A) => B, g: (y: B) => C): (x: A) => C {
    // ...
}

let boxElements: <T>(a: T) => { value: T[] } =
    compose(x => [x], y => { value: y });

Currently this doesn't work well - when we get the contextual type for x, we get it from the erased signature of <T>(a: T) => { value: T[] }, which is really just (a: any) => { value: any[] }.

We will have a PR that will help fix this.

Q: What about constraints?
A: Constraints will be carried through.

We will still have some problems with compositional patterns without explicit types.
For example:

declare function compose<A, B, C>(f: (x: A) => B, g: (y: B) => C): (x: A) => C;
declare function box<T>(x: T): { value: T };
declare function list<U>(x: U): U[];

compose(list, box);

The problem is that TypeScript draws the following inferences:

Type Parameter Inferences
A U
B U[], T
C { value: T }

The way we walk through arguments (simple and left-to-right) and draw inferences simply isn't sufficient - we need to find a way to unify these type parameters.

But it's not just a matter of throwing unification at the type system. So the current question is how do we introduce some unification to the current process. Perhaps it will be a "last resort" process. And this will be exploratory work.

@gcnew did do great work, but pointed out many of the difficulties and roadblocks you can run into.

Changing default target to ES5

  • Very strange that we wouldn't simply move the the higher one?
  • Why take a breaking change when we'll need to make another breaking change in the future?
  • Are there a lot of people running into this problem?
    • Doesn't appear that a lot of people have been complaining about it.

Pure annotation in downlevel emits

  • Currently, Uglify doesn't understand when our class emit.
    • It would be great if Uglify could operate on the ES2015 code.
  • We just want to tell other tools it's a class - onus of determining side-effects being on TypeScript is probably more questionable than an optimizer doing so.
  • Decision: emit JSDoc @class comment unconditionally.

Lib reference directive (#15780)

  • /// <reference lib="name" />

  • Problem: things like corejs on DefinitelyTyped conflict with compiler defaults.

  • This means could simply be reduced to /// <reference lib="es2015.d.ts" />.

  • Q: What about /// <reference no-default-lib="true"/>?

    • This PR ignores any /// <reference no-default-lib="true"/> comments.
  • Could also do /// <reference lib="..." /> in lib.d.ts as well.

    • Let's do that.
  • What about Daniel's lib versioning idea of publishing to @types?

    • Example: DOM APIs require new logic - suddenly breaks certain builds.
    • People would be able to go to a specific version of a lib if they got broken, or just lock down all their dependencies.
    • Also might allow us to bring node.d.ts in.

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