Skip to content

Design Meeting Notes, 2/1/2023 #52579

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

Closed
RyanCavanaugh opened this issue Feb 2, 2023 · 2 comments
Closed

Design Meeting Notes, 2/1/2023 #52579

RyanCavanaugh opened this issue Feb 2, 2023 · 2 comments
Labels
Design Notes Notes from our design meetings

Comments

@RyanCavanaugh
Copy link
Member

  • Intersection state Consistently propagate intersectionState in relations #52392
    • Unifies the interaction of excess property checking and weak types
    • Key logic is in structuredTypeRelatedTo, dealing with properties which are nested in the intersection, e.g.
      • { a: { x: string } } & { c: number } , we need to deal with both the intersection type and its final form
      • Contrast with something like { a: { x: string } } & { a: { y: number } } - a contextual-agnostic analyis can't handle this correctly
      • Interacts with isDeeplyNestedType, which exists to prevent runaway stackoverflows in generatively-recursive types
        • The "identity key" here is, for example, the symbol of a declared type
        • For intersections, no such durable/reusable identity key existed
        • This meant we couldn't safely plumb to more than a fixed depth (1) of intersections when looking for excess properties
      • Fix: Instead, an intersection is deeply nested if any of its constituents is deeply nested
        • Now we don't need a fixed depth limit
      • Fix is good, everything's passing
      • Check time for vuelidate on DT has doubled, but really only because we're doing work we should have been doing the whole time
      • 5.0 or 5.1?
        • It's a bugfix, standard level of riskiness, 5.0.
  • Widening/nonwidening enum literals Widening and non-widening computed enum types #52542
    • In 5.0 we unified enum logic, yay
    • Consider enum E { A = 1, B = 2, C = 3}
      • Type E is a union, E.A | E.B | E.C
    • Contrast enum X { A = compute(0), B = compute(1), C = compute(2) }
      • Old behavior: type X is just X, a subtype of number
      • New behavior: type X is a union of X.A | X.B | X.C, pretty much the same as E, each of which is an opaque subtype of number
    • All motivating scenarios that led to fresh/nonfresh widening/nonwidening literal types for string/numeric literals now apply to these opaque (nonliteral) types
    • e.g. let a = E.A;, a = E.B; should be legal
    • Declaration file emit allows for initializers so that you can get both behaviors despite the fresh and nonfresh types having identical names
    • 👉 5.0
  • export ordering (TC39 update)
    • Order 1: @decorator export class X {
    • Order 2: export @decorator class X {
    • Order 1 is the longstanding order in TS
    • Order 2 came into existence due to a transcription error when writing the proposal
    • Upon fixing the error, concerns were raised
      • What if you want to "decorate an export" ?
        • What does this mean?
          • Sort of unclear, all possible things you could do here violate critical static invariants
      • Various arguments ad linguistics of what's an adverb, adjective, conjunction junction what's your arrow function, etc.
      • What if you want to have different behaviors between Order 1 and Order 2?
        • But what?
        • At best, you could have the inner and outer names of a class refer to the undecorated / decorated values, but this is a footgun
          • If desired you can use proxies
        • If this is legal, then @deco1 export @deco2 class A { becomes legal and sensical (!)
    • TC39 Discussion continued for a long time without progress
    • Decorators went to stage 3 without this being addressed
    • Today
      • export @decorator class is legal per TC39
      • In 5.0 today:
        • In TS files, both orderings are supported with identical semantics
        • In JS files, only export @decorator class is supported under non-experimental-decorators
    • This has implications for Function#toString since decorators are supposed to be part of toString but not export
      • Arguments about eval(someClass.toString()) but this is not an existing invariant anyway (?)
    • Do we need a transitional flag?
    • Quickfix? Tool? Regular expression?
      • These tools don't work on documentation on the internet
        • This is an argument for making the proposal change, not making the behavior available in TS when it doesn't actually exist
    • What are other transpilers doing?
      • If we allow this (illegal!) syntax, then every TS-compatible transpiler has to as well, and it's a de facto JS feature
      • But it's effectively moot since (all?) transpilers already presumably support experimentalDecorators
      • Babel issues a specific error
    • Conclusions:
      • Hope that both-orderings proposal goes through at TC39 and we don't have to make a tough decision
      • Otherwise, circle back and argue about allowing flagged, unflagged, or not at all
    • Update 2/2/23: Most of this turned out to be moot because both orderings were accepted at TC39 today 🎉
@RyanCavanaugh RyanCavanaugh added the Design Notes Notes from our design meetings label Feb 2, 2023
@RyanCavanaugh RyanCavanaugh changed the title Design Meeting Notes, 2/2/2023 Design Meeting Notes, 2/1/2023 Feb 2, 2023
@fatcerberus
Copy link

Order 2 came into existence due to a transcription error when writing the proposal

Interesting that this was unintentional; I really like that export @deco class ended up being a thing since for multiline definitions I prefer to put export on its own line to make it immediately obvious what’s being exported while scrubbing through a large file.

export
class Foo {
    // ...
}

Even for single-line definitions it’s nice to have all the exports at the beginning of the line.

@Jack-Works
Copy link
Contributor

What if you want to "decorate an export" ?
What does this mean?
Sort of unclear, all possible things you could do here violate critical static invariants

Ideally, decorating an export does not require code to be run in the link stage so I don't think it will violate static invariants.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Design Notes Notes from our design meetings
Projects
None yet
Development

No branches or pull requests

3 participants