Skip to content
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, 3/2/2018 #22304

Closed
DanielRosenwasser opened this issue Mar 2, 2018 · 0 comments
Closed

Design Meeting Notes, 3/2/2018 #22304

DanielRosenwasser opened this issue Mar 2, 2018 · 0 comments
Labels
Design Notes Notes from our design meetings

Comments

@DanielRosenwasser
Copy link
Member

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>
@DanielRosenwasser DanielRosenwasser added the Design Notes Notes from our design meetings label Mar 2, 2018
@microsoft microsoft locked and limited conversation to collaborators Jul 3, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Design Notes Notes from our design meetings
Projects
None yet
Development

No branches or pull requests

1 participant