Skip to content

Design Meeting Notes, 11/3/2017 #19722

@DanielRosenwasser

Description

@DanielRosenwasser

Stricter Tuple Types

#17765

  • Tried freshness, generally encountered strange behavior.
  • Adding an explicit length property breaks fairly little
    • Things we catch:
      • Accidental Haskell-style list syntax: [T] instead of T[].
        • This is actually a singleton tuple of T instead of Array<T>
        • Caught ~10 instances of that.
    • Actual errors where people misunderstood the API
      • Found this in Highcharts & Leaflet
    • Downside is you can't cast between these anymore without an intermediate.
    • One break in firebase-js-sdk
  • Then we tried changing tuples to extend ReadonlyArray instead.
    • Which makes tuple elements immutable which is more debatable.
    • And problematically means you can't assign to array
    • Didn't find many errors outside of the test suite.
    • Added another break in firebase-js-sdk
  • What about push: never; pop: never;?
  • Conclusion: try out the stubs, keep testing on real world code.

instanceof checks

#19671

  • Idea: instanceof has worked structurally since forever with us.
    • But because of structural compatibility, things that were structurally identical would act very strangely.
    • We want to change this to actually check the base types as it does at runtime.
  • Things the PR does
    • Makes instanceof nominal

    • Changes to subtype reduction to accomodate this new behavior.

    • Take the following:

      class A {}
      class B extends A {}
      
      class Q extends A { qProp: any; }
      
      let blah = Math.random() ? new B() : new Q();
    • Under old subtype reduction behavior, blah has type B; means the negative check for blah instanceof B gives you never:

      if (blah instanceof B) {
          blah; /* has type `B` */
      }
      else {
          blah; /* has type `never` */
      }
    • Under new behavior, we aren't as agressive; blah has type B | D

      if (blah instanceof B) {
          blah; /* has type `B` */
      }
      else {
          blah; /* has type `D` */
      }
    • This is better, but it affects things like callability.

  • Do we care about how ES2015 allows this behavior to be overridden with Symbol.instanceOf?
    • Most people just don't do this.
  • It's in nightly now.

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