Skip to content

Design Meeting Notes, 3/2/2018 #22304

@DanielRosenwasser

Description

@DanielRosenwasser

More Special Declaration Types in JS

#21974

In 2.7, we started treating variables initialized with empty object literals as namespaces in JS files.

var foo = {};
foo.x = 10
foo.y = 20;

Now you can omit the var

app = {};
app.C = function() { 
    // ...
}

Also allows IIFEs to be namespaces.

var C = (function () {
    function C(n) {
        this.p = n;
    }
    return C;
})();

[[Daniel: I'm going to stop here because you can just read the PR writeup.]]

  • We need to put these together in one document.
  • Why do we do this in JavaScript and not in TypeScript?
    • We're supposed to be a superset.
    • What about declaration emit?
      • Would we serialize using the TS-specific syntax?
    • Should we only recognize this with var declarations as opposed to just consts?
      • Can always re-assign to a var.
  • It is currently still awkward to transition from a .js file to a .ts file.
    • You switch to .ts and you become temporarily untyped even if you want
    • What about a mode that enables these constructs in .ts?
    • What about if allowJs just permitted this?
      • How do you disable the behavior though?
        • When do you want to disable it?
          • When you want to start writing super-strict .ts in existing JS code.
    • "I'm worried about having too many flags"
      • [[laughter]]
  • What about initializing fields in a class?
    • TypeScript requires fields to be declared up-front
    • How do you prevent misspelled properties?
  • Conclusion: we will think harder!

The unknown type

#10715

  • Prototyped it as a new primitive type.
  • Doesn't have to be a new primitive type.
    • In non-strict mode, everything is assignable to {} except for void.
    • In strictNullChecks, you get a problem because you have to write {} | null | undefined; it's annoying.
    • Can just write an alias!
      • That way you can still get narrowing; check != null and then you'll be able to call toString() on it.
  • Problem: If we put this in lib.d.ts, you can run with skipLibCheck and TypeScript won't always print that out because it won't have seen the alias.
    • We could fix this in strictNullChecks mode by forcing the checker to resolve this.
    • But then in non-strictNullChecks mode,
  • What about failed type argument inference?
    • Could default to unknown instead of {}?
    • But not clear you get a lot of value from that.
    • Could also not do anything.
    • Problem: implies you'd need to change the constraint; implementations of generic functions currently make the assumption that type parameters will not be null or undefined (constraint is implicitly {}).
  • We want it highlighted as a keyword though...
    • So should it be an alias?
  • Open questions
    • Does x > 0 imply narrowing?
      • No.
    • if (x) narrows to {}?
      • Yes.
    • if (!x) narrows to {} | null | undefined?
      • Yes.
      • Currently no?
      • @chancancode reported this and we said "ehhhh"
    • What does { [s: string]: unknown } mean?
      • Problems with dictionaries becoming assignable to anything.
    • What's the type of unknown | T?
      • Question becomes "should we collapse unions containing {}?
        • Probably yes?
      • But then you lose the contextual type in some cases, which would break a bunch of React code.
        • We need to see what people are doing on DefinitelyTyped and see what the intent is there.
          • Should write a TSLint rule to track them down.
    • What's the type of s!?
      • {}
      • (as opposed to object | string | number | boolean).

Distribute keyof on intersections

#22300

This now works as expected!

type X<A, B> = Record<A, object> & Record<B, object>

// keyof A | keyof B
type Y<A, B> = keyof X<A, B>

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