New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Design Meeting Notes, 9/9/2016 #10826

Closed
DanielRosenwasser opened this Issue Sep 9, 2016 · 0 comments

Comments

Projects
None yet
1 participant
@DanielRosenwasser
Member

DanielRosenwasser commented Sep 9, 2016

Always Infer Literal Types (#6554, #10676)

Basics

  • Based on complaints we've seen in the past about how literals don't "stick" for const

    // Type has type 'string' instead of '"hello"'
    const x = "hello";
  • Idea: the literal 1 should always start out with the type 1.

    • No more literal type locations.
    • In a read-only location, a literal type will keep its type.
    • In a mutable location, a literal type will gain its base primitive type, unless it has a contextual type.
  • Every literal type has a base primitive type.

Changes to Function Return Type Inference

  • Other change is that multiple return statements always return a union of each returned type.
  • For a singleton literal type, widen to the base primitive type.
    • Rationale - definitely no point to inferring a singleton. Arguable whether you want the same behavior on unions.

Changes to Type Argument Inference

For a type parameter T, a literal type argument will be inferred for T if

  • T is inferred from "top-level" occurrences (allows widening to take place later on).
  • T has no primitive/literal constraint (user wanted it).
  • T does not occur at the "top-level" in the return type (more complicated reasons).

Substitute Value of super() For this (#7574, #10762)

Summary:

  • Not pretty.
  • Not that bad.
  • Perf numbers aren't much worse.

👍

@mhegazy notes:

  • Issue: #7574
  • PR: #10762
  • ES6 semantics for inheritance indicates that the result of calling super becomes the new this
  • This is why this cannot be used before super is called.
  • perf tests on the generated output seems to be on par with the previous emit, no major slowdowns
  • This does not completely handle cases requiring new.target e.g. extending Array and Error
  • The output is not as clean as it was. but not different from capture of this in arrow functions
  • 👍

keysof Operator (#1295, #10425)

Libraries like Ember, Backbone, and Immutable all use string literals to access properties.

Idea keysof T: a "keys query", which returns a union of literal types for each property in T.
Following this, you could have T[K] which, when K is a literal type, returns the type of a property with the name K on T.

function get<T, K extends keysof T>(obj: T, key: K): T[K] {
    obj[key];
}

// Returns 'string'
get({name: "Daniel" }, "name");

// Error: '{ name: string }' has no property named 'nmae'.
get({name: "Daniel" }, "nmae");
  • Question: Why doesn't key just have the type keysof T?
    • Because if T was something like { name: string; age: number }, then keysof T would be "name" | "age".
      Even if you pass in "name" for key, the type system keeps the type as "name" | "age".
      That means the return type will be T["name" | "number"].
      In reality, you want to grab the specific literal "name" to do a query.
      • We could do the "right thing", but that'd require an implicit type parameter, which would get complicated.

Caveats: any object contxtually typed with a string index signature will have keysof effectively return string on it.

@Microsoft Microsoft locked and limited conversation to collaborators Jun 19, 2018

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.