Skip to content

Design Meeting Notes, 6/16/2017 #17501

@DanielRosenwasser

Description

@DanielRosenwasser

"Dynamically" named properties (for symbols, string literals, and numeric literals)

  • Added a late-binding stage to get the symbol of something that could potentially be a literal type.
  • Things with an anonymous name would internally get a __anonymous symbol.

Unique symbol types

  • Two calls to the Symbol() function will always produce a completely unique value.
    • The type of a unique symbol is called symbol() - notice the postfix parentheses.
  • symbol() is a subtype of the symbol type.
  • Like literal types, these types contain "freshness" which can be widened away to produce a "regular" type.
    • Why do we do freshness for these types?
      • It's just a signal to the language - if you have a regular type, that means that you need to find the original declaration for printing the type in .d.ts emit.
      • We need to have some declaration for original & aliasing declarations.
        • Suggestion: Instead of relying on freshness, why not just say "this is always the declaration of x unless I am printing out the type of x.
  • It's an error to use symbol() in positions other than readonly bindings.

Example:

const x = Symbol();

// has type 'typeof x'
const y = x;

const z = "field";

interface Foo {
    [x]: number;
    [z]: string;
}

declare const obj: Foo;

obj[y]; // number
obj[z]; // string
  • When you alias a symbolic const with another const, it has the type typeof [[that original variable]].

  • Q: What about interface merging?

    interface SymbolConstructor {
        readonly iterator: symbol();
    }
    
    interface SymbolConstructor {
        readonly iterator: symbol();
    }
    • This works
  • Q: Comparability?

    • Two distinct fresh symbol types are not comparable at all.
      • Note: need to have a better error message when doing so. Right now says symbol() is not comparable to symbol().
  • Syntax?

    • new symbol?
  • Should try this out on some real world motivated examples.

  • Bonus: we can simplify the compiler because we don't have to check for well-known names on the global Symbol constructor.

Regaining Perf

  • Parse & bind times have stayed around the same.

  • Check & emit have gotten slightly slower.

    • But even slight increases build up.
    • Some changes we had that bought us perf were things like changing to ES Maps instead of plain objects.
      • But now we're almost back to the speed we had back in November.
  • Well we unconditionally bring each of the transformers into memory.

    • But engines often don't run code until they're needed.
    • Plus that's been in place for a while - doesn't address the root cause.
  • We need to update our CI reports to use updated numbers for compile times.

  • Bottom line: there's no free lunch. Whenever we add code, we get slower.

    • Be judicious about adding code.
  • Action item: set up a brown bag on how to run benchmarks etc.

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